我正在关注step 6 of this guide使用php sdk更新客户的信息。我们的想法是通过其id检索客户并为该客户发出更新请求。我的代码:
$ipp_customer = $data_service->FindById(
new IPPCustomer( array('Id' => '120'), true)
);
$ipp_customer->sparse = 'true';
$ipp_customer->DisplayName = 'Carrier Name';
$data_service->Update($ipp_customer);
我在更新响应时收到验证错误(错误代码2090)。在生成更新请求时,SDK似乎没有用0填充SyncToken。这导致验证错误。
然后我查看了php SDK中提供的示例代码(/v3-php-sdk-2.0.1/_Samples/CustomerUpdate.php)。示例代码使用$dataService->Add
来执行更新。调用Add
的结果请求没有SyncToken
,因此示例代码似乎不适用。
如何正确使用SDK来更新客户?
请求/响应消息如下:
REQUEST BODY
=============
<?xml version="1.0" encoding="UTF-8"?>
<ns0:Customer xmlns:ns0="http://schema.intuit.com/finance/v3" sparse="true">
<ns0:Id>120</ns0:Id>
<ns0:SyncToken/>
<ns0:MetaData>
<ns0:CreateTime/>
<ns0:LastUpdatedTime/>
</ns0:MetaData>
<ns0:FullyQualifiedName/>
<ns0:DisplayName>Carrier Name</ns0:DisplayName>
<ns0:PrintOnCheckName/>
<ns0:Active>true</ns0:Active>
<ns0:PrimaryPhone>
<ns0:FreeFormNumber/>
</ns0:PrimaryPhone>
<ns0:Fax>
<ns0:FreeFormNumber/>
</ns0:Fax>
<ns0:Taxable>false</ns0:Taxable>
<ns0:BillAddr>
<ns0:Id>87</ns0:Id>
<ns0:Line1/>
<ns0:Line2/>
<ns0:City/>
<ns0:CountrySubDivisionCode/>
<ns0:PostalCode/>
<ns0:Lat/>
<ns0:Long/>
</ns0:BillAddr>
<ns0:Job>false</ns0:Job>
<ns0:BillWithParent>false</ns0:BillWithParent>
<ns0:Balance>0</ns0:Balance>
<ns0:BalanceWithJobs>0</ns0:BalanceWithJobs>
<ns0:PreferredDeliveryMethod/>
</ns0:Customer>
RESPONSE BODY
=============
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-01-21T12:53:53.838-08:00">
<Fault type="ValidationFault">
<Error code="2090" element="SyncToken">
<Message>Invalid Number</Message>
<Detail>Invalid Number : </Detail>
</Error>
</Fault>
</IntuitResponse>
感谢。
修改1 以下是FindById调用的结果:
RESPONSE BODY
=============
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2014-01-24T10:21:58.493-08:00">
<Customer domain="QBO" sparse="false">
<Id>120</Id>
<SyncToken>13</SyncToken>
<MetaData>
<CreateTime>2014-01-17T14:08:42-08:00</CreateTime>
<LastUpdatedTime>2014-01-24T09:27:00-08:00</LastUpdatedTime>
</MetaData>
<FullyQualifiedName>Carrier Name Modif</FullyQualifiedName>
<DisplayName>Carrier Name Modif</DisplayName>
<PrintOnCheckName>Carrier Name</PrintOnCheckName>
<Active>true</Active>
<Taxable>false</Taxable>
<BillAddr>
<Id>87</Id>
</BillAddr>
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<Balance>0</Balance>
<BalanceWithJobs>0</BalanceWithJobs>
<PreferredDeliveryMethod>Print</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
编辑2 我使用示例脚本(CustomerUpdate.php)并使用我的应用程序代码(这是一个cakephp webapp)通过SDK进行了调试。使用print_r,示例脚本对FindById的调用产生了一个带有SyncToken输出的IPPCustomer:
[SyncToken] => 46
我的应用程序代码对FindById的调用产生了:
[SyncToken] => String Object
(
[value] => 46
)
这个结果使我相信由于某些上下文差异,xml到对象的解析会有不同的处理方式。 cakephp定义了一个String类,可供应用程序代码使用。
在v3-php-sdk-2.0.1 / Dependencies / XDS2PHP / src / com / mikebevz / xsd2php / Bind.php中,函数bindXml调用class_exists
(第138行)。以下是摘录:
if (!class_exists($class_name)) {
// assign $model->{$name} to child node's value
} else {
// assign $model->{$name) to newly created object $class_name, which wraps child nodes' value
}
使用cakephp(我的应用程序代码)时,class_exists('string')
的计算结果为true。不使用cakephp(示例脚本)时,class_exists('string')
的计算结果为false。我相信这就是使用这个库时xml-to-object解析行为不同的原因。因此,我得到
<ns0:SyncToken/>
而不是预期的
<ns0:SyncToken>46</ns0:SyncToken>
似乎已经定义了String类的cakephp遇到了与IPP PHP SDK的冲突情况。通过将以下行添加到示例CustomerUpdate.php脚本中,可以重新创建这种冲突的情况:
require_once('cake/libs/string.php'); // assuming cakephp 1.3's string class
我认为问题现在更清楚了,对解决方案有什么建议吗?
答案 0 :(得分:2)
您可以使用“添加”来使代码正常工作。
$ipp_customer = $dataService->FindById(
new IPPCustomer( array('Id' => '6'), true)
);
$ipp_customer->DisplayName = 'Name Name Something';
$dataService->Add($ipp_customer);
这在我的QuickBooks设置中成功更新了ID为6的用户的显示名称。它也适合你。
答案 1 :(得分:0)
很抱歉,如果我的回复迟到了。我遇到了和Eric一样的问题,谢谢你指点我/dpendencies/XDS2PHP/src/com/mikebevz/xsd2php/Bind.php文件的方向。
我为此实现的解决方法是测试是否存在Controller对象(存在于cakephp环境中)
我最终取代了这个:
if (!class_exists($class_name)) {
使用:
if (!class_exists($className) || (($className == 'string') && class_exists('Controller'))) {
现在dataService-&gt; Update调用正在按预期工作。