robgridley/pace-api

EFI Pace API 客户端

2.0.5 2022-10-13 17:29 UTC

This package is auto-updated.

Last update: 2024-09-13 21:53:02 UTC


README

这是一个非官方的PHP客户端库,用于EFI Pace的SOAP API,由一名Pace管理员和PHP开发者创建。此库对一些约定进行了假设,以使您的使用更加方便。

安装

通过 Composer 安装

$ composer require robgridley/pace-api

测试

ModelKeyCollectionXPath\Builder 类提供100%代码覆盖率的PHPUnit测试。

运行测试

$ composer test

待办事项

  • 为剩余的类编写测试
  • 实现剩余的Pace服务(例如“InvokeProcess”)

配置

您需要创建一个带有“允许远程API使用”启用的Pace系统用户。

use Pace\Client as Pace;
use Pace\Soap\Factory as SoapFactory;

$pace = new Pace(new SoapFactory(), 'epace-staging.domain.com', 'apiuser', 'apipassword');

CRUDD

创建对象

要创建 Pace 中的新对象,从 Pace 客户端获取模型,设置其属性,然后调用 save() 方法。您可以通过调用 model() 方法或使用动态属性来检索模型实例。

$csr = $pace->model('CSR');
// or the shorter, prettier:
$csr = $pace->csr;

$csr->name = 'John Smith';
$csr->email = 'jsmith@domain.com';
$csr->save();

读取对象

您可以通过主键读取对象,这将返回一个单独的模型。

$csr = $pace->csr->read(1);

echo $csr->email; // prints "jsmith@domain.com"

复合键由冒号分隔。

$jobPart = $pace->jobPart->read('12345:01');

更新对象

除了创建对象外,save() 方法还用于更新现有对象。

$csr = $pace->csr->read(1);

$csr->active = false;
$csr->save();

复制对象

要复制现有对象,首先加载现有对象,可选地修改其属性,然后调用 duplicate() 方法。将返回一个新的模型实例,并将现有模型恢复到其原始状态。

duplicate() 方法接受一个可选参数:新的主键值。如果您不提供主键,则 Pace 在大多数情况下会自动递增。

$csr = $pace->csr->read(1);
$csr->name = 'Jane Smith';
$newCsr = $csr->duplicate();

echo $csr->name; // prints "John Smith"
echo $newCsr->name; // prints "Jane Smith"

删除对象

delete() 方法接受一个可选参数:模型的唯一键名称。如果没有提供,它将进行猜测。

$csr = $pace->csr->read(1);
$csr->delete();

查找对象

基础

Pace的Web服务使用XPath表达式来查找对象。包含的XPath.Builder类负责将PHP原生类型转换为XPath表达式,并使您的过滤器更易于阅读(在PHP编辑器中)。

查找多个对象

$jobs = $pace->job
	->filter('adminStatus/@openJob', true)
	->filter('@jobType', 1)
	->find();

上述操作返回一个模型集合。

查找单个对象

$csr = $pace->csr->filter('@name', 'Jane Smith')->first();

上述操作返回单个模型实例。

运算符

客户端支持 Pace 支持的所有运算符:=!=<><=>=。还支持 startsWith()contains()

$millionPlus = $pace->salesPerson->filter('@annualQuota', '>=', 1000000)->find();

$coated = $pace->inventoryItem->contains('@description', 'C2S')->find();

$tango = $pace->inventoryItem->startsWith('@description', 'Tango')->find();

分组过滤器

有时您可能需要分组过滤器以创建更复杂的条件。

$customers = $pace->customer
    ->filter('@state', 'ON')
    ->filter(function ($xpath) {
        $xpath->filter('@city', 'Toronto');
        $xpath->orFilter('@city', 'Ottawa');
    })
    ->find();

如您所见,传递闭包创建一组嵌套的条件。

排序

使用 sort() 方法对结果进行排序。该方法接受两个参数:一个用于指定排序字段的XPath表达式和一个布尔值,用于确定方向,默认值为 false(升序)。您可以链式调用多个排序,尽管我不确定 Pace 是否有限制。

$jobs = $pace->job
	->filter('adminStatus/@openJob', true)
	->sort('customer/@custName')
	->sort('@job', true)
	->find();

日期

日期会自动转换为和从 Carbon 实例。如果您想了解这是如何发生的,请查看 Soap\DateTimeMapperSoap\Factory 类。

键集合

查找对象SOAP调用的原始结果是主键数组。模型类会自动将该数组封装在KeyCollection对象中,为您提供一系列便利,并防止不必要的调用读取对象服务,只按需加载模型。

您可以将KeyCollection像数组一样循环遍历。每次迭代时都会加载模型,所以如果例如您退出循环,剩余的模型将不会被加载。

$estimates = $pace->estimate->filter('@entryDate', '>=', Carbon::yesterday())->find();

foreach ($estimates as $estimate) {
	if ($estimate->enteredBy == 'jsmith') {
		echo "John has entered an estimate since yesterday!"
		break;
	}
}

KeyCollection还具有许多有用的方法,如all()paginate()first()。事实上,之前单独对象查找的示例只是对KeyCollection::first()方法的快捷方式。

关系

加载相关模型

您可以通过动态方法自动加载相关模型。

对于“属于”关系,模型属性名和外部模型类型必须匹配。例如,Customer对象有一个名为'csr'的属性,其中包含'CSR'对象类型的主键。

以下返回单个模型。

$customer = $pace->customer->read('HOUSE');
$houseCsr = $customer->csr();

要加载“拥有多个”相关模型,调用外部模型类型的驼峰式复数形式。假设外部模型将父模型的主键存储在以父模型类型命名的属性中。例如,'Job'对象将'Customer'对象的主键存储在名为'customer'的属性中。

以下返回一个XPath\Builder对象。您可以选择性地添加额外的相关模型过滤器。

$customer = $pace->customer->read('HOUSE');
$houseJobs = $customer->jobs()->filter('@adminStatus', 'O')->get();

如果您发现一个违反常规的对象,可以直接调用公共的belongsTo()hasMany()方法。

以下两个示例是相同的。

$notes = $customer->customerNotes()->get();
$notes = $customer->hasMany('CustomerNote', 'customer', 'id')->get();

在第一个示例中,所有必要的参数都是猜测的。在第二个示例中明确提供了它们。

复合键

已添加对加载具有复合键的相关模型的初始支持。调用hasMany()belongsTo()方法,传递包含字段名称(包含键)并用冒号分隔的字符串。

$jobPart = $pace->jobPart->read('12345:01');
$jobMaterials = $jobPart->hasMany('JobMaterial', 'job:jobPart')->get();

关联相关模型

如果您要关联的模型具有可猜测的主键,则可以将模型作为属性值分配。否则,您需要显式分配主键值。

$batch = $pace->inventoryBatch;
$batch->save(); // save the model to generate a primary key

$line = $pace->inventoryLine;
$line->inventoryBatch = $batch;

事务

您可以将操作包装在数据库事务中,以便在发生错误时回滚所有调用。使用事务的好处是可以将事件处理器推迟到所有API调用完成。

注意:事务服务是在Pace 29.0-1704中引入的。

使用闭包

使用transaction()方法在数据库事务中执行操作。如果发生服务器端错误,Pace将回滚事务,并且如果抛出PHP异常,API客户端将自动回滚事务。如果闭包执行成功,且没有服务器端错误,则提交事务。

$pace->transaction(function () use ($pace) {
    $job = $pace->model('Job');
    $job->customer = 'HOUSE';
    $job->description = 'Test Order';
    $job->jobType = 10;
    $job->adminStatus = 'O';
    $job->save();

    $jobPart = $job->jobParts()->first();

    $jobMaterial = $pace->model('JobMaterial');
    $jobMaterial->job = $jobPart->job;
    $jobMaterial->jobPart = $jobPart->jobPart;
    $jobMaterial->inventoryItem = 'ABC123';
    $jobMaterial->plannedQuantity = 100;
    $jobMaterial->save();

    throw new Exception('Just kidding. Roll it back.');
});

手动使用事务

或者,您可以手动调用startTransaction()rollbackTransaction()commitTransaction()方法。

$pace->startTransaction();

$csr = $pace->model('CSR');
$csr->name = 'Definitely Not Evil';
$csr->save();

if ($csr->id == 666) {
   // Oh no. They are evil!
   $pace->rollbackTransaction();
} else {
   $pace->commitTransaction();
}

JSON

Model和KeyCollection类都实现了JsonSerializable接口,将任一类转换为字符串将生成JSON。

// print a JSON representation of the House account
echo $pace->customer->read('HOUSE');

附件

附加文件

要将文件附加到模型,您只需指定其名称和内容。库会处理猜测MIME类型和编码内容。

$job = $pace->model('Job')->read('12345');
$attachment = $job->attachFile('test.txt', file_get_contents('test.txt'));
$attachment->description = 'A test file';
$attachment->save();

attachFile()方法返回FileAttachment模型,您可以设置类别、描述等。只有当您更改任何属性时才调用save()方法。

您还可以通过指定字段的名称将文件附加到字段。这在整个Pace中用于标志、照片、布局等。

$company = $pace->model('Company')->read('001');
$company->attachFile('logo.png', file_get_contents('logo.png'), 'logo');

检索附加文件

模型关联的文件通过特殊的关系方法检索。它类似于“多对一”关系,并返回一个 XPath.Builder 实例。

$attachments = $job->fileAttachments()->get();

使用 filter() 限制结果到一个字段或一种文件类型。

$logo = $company->fileAttachments()->filter('@field', 'logo')->first();
$spreadsheets = $job->fileAttachments()->filter('@ext', 'xls')->get();

最后,在 FileAttachment 模型上调用 getContent() 以读取文件内容。库会自动为您解码内容。

$attachment->getContent();

报告

使用报告生成器流畅地运行报告。

传递参数

使用 parameter()namedParameter() 方法向报告传递参数。 parameter() 方法接受两个参数:报告参数 ID 和值。

$pace->report(1000)
   ->parameter(10001, '2019-12-01')
   ->parameter(10002, '2019-12-31')
   ->parameter(10003, 'D');

namedParameter() 方法通过名称查找报告参数 ID。

$pace->report(1000)
   ->namedParameter('Start Date', '2019-12-01')
   ->namedParameter('End Date', '2019-12-31')
   ->namedParameter('Report Format', 'D');

需要基础对象的报告

某些报告需要基础对象。使用 baseObjectKey() 方法传递模型或主键。

$job = $pace->model('Job')->read('90000');

$pace->report(100)
    ->baseObjectKey($job)
    ->namedParameter('Include Kit Detail', 'N');

获取报告

报告生成器的 get() 方法返回一个 Report\File 实例,它有两个公共方法:getContent() 返回报告文件内容,getMediaType() 返回文件的媒体(MIME)类型。

$file = $pace->report(200)->get();

if ($file->getMediaType() == 'application/vnd.ms-excel') {
    file_put_contents('report.xls', $file->getContent());
}

打印报告

使用 print() 方法将报告打印到默认打印机。如果报告没有配置默认打印机,Pace API 将抛出 SOAP 错误。

$pace->report(100)
    ->baseObjectKey('90000')
    ->namedParameter('Include Kit Detail', 'N')
    ->print();

版本

识别服务器上运行的 Pace 版本。

$pace->version();

上述将返回

array(4) {
  ["string"]=>
  string(24) "27.12-750 (201512111349)"
  ["major"]=>
  int(27)
  ["minor"]=>
  int(12)
  ["patch"]=>
  int(750)
}