du1108 2014-01-21 21:17
浏览 37
已采纳

QBO IPP PHP SDK QuickBooks V3 API - 无法更新客户

I am following step 6 of this guide to update a customer's information using the php sdk. The idea is to retrieve the customer by its id and issue an update request for that customer. My code:

$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);

I get a validation error (error code 2090) on the response for the update. It seems the SDK is not populating SyncToken with 0 when generating the update request. This resulted in the validation error.

Then I looked at the sample code provided in the php SDK (/v3-php-sdk-2.0.1/_Samples/CustomerUpdate.php). The sample code uses $dataService->Add for performing the update. The resulting request of calling Add doesn't have SyncToken, so the sample code does not seem applicable.

How to use the SDK correctly to update a customer?

The Request/Response messages are as follow:

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>

Thanks.

Edit 1 Here is the Response body as a result of FindById call:

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>

Edit 2 I debugged through the SDK using the sample script (CustomerUpdate.php) and using my application code (which is a cakephp webapp). Using print_r, the sample script's call to FindById produced an IPPCustomer with SyncToken outputs:

[SyncToken] => 46

My application code's call to FindById produced:

[SyncToken] => String Object
  (
    [value] => 46
  )

This result led me to believe the xml-to-object parsing is handled differently due to some contextual differences. cakephp has a String class defined and is available for use by the application code. In v3-php-sdk-2.0.1/Dependencies/XDS2PHP/src/com/mikebevz/xsd2php/Bind.php, the function bindXml makes a call to class_exists (around line 138). The following is an excerpt:

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
}

The class_exists('string') evaluates to true when using cakephp (my application code). The class_exists('string') evaluates to false when not using cakephp (the sample script). I believe this is why the xml-to-object parsing behaves differently when using this library. Consequently, I get

<ns0:SyncToken/>   

instead of the expected

<ns0:SyncToken>46</ns0:SyncToken>

It seems cakephp, having defined String class, runs into a conflict situation with IPP PHP SDK. This conflicting situation can be re-created by adding the following line to the sample CustomerUpdate.php script:

require_once('cake/libs/string.php'); // assuming cakephp 1.3's string class

I think the problem is more clear now, any suggestions for a solution?

  • 写回答

2条回答 默认 最新

  • duanlin6989 2014-07-17 18:18
    关注

    Sorry if my response comes late. I ran into the exact same issue as you Eric, thank you for pointing me in the direction of the /Dependencies/XDS2PHP/src/com/mikebevz/xsd2php/Bind.php file.

    The workaround I've implemented for this was to test for the presence of a Controller object(exists in a cakephp environment)

    I ended up replacing this :

    if (!class_exists($class_name)) {
    

    With:

    if (!class_exists($className) || (($className == 'string') && class_exists('Controller'))) {
    

    Now the dataService->Update call is working as expected.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line