0

我正在關注step 6 of this guide以使用php sdk更新客戶的信息。這個想法是通過它的id檢索客戶,併爲該客戶發出更新請求。我的代碼:QBO IPP PHP SDK QuickBooks V3 API - 無法更新客戶

$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我通過SDK使用樣品腳本(CustomerUpdate.php),並使用我的應用程序調試代碼(這是一個cakephp webapp)。使用的print_r,示例腳本對FindById通話產生的IPPCustomer與SyncToken輸出:

[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 
} 

class_exists('string')使用CakePHP(我的應用程序代碼)時,計算結果爲真。當不使用cakephp(示例腳本)時,class_exists('string')的計算結果爲false。我相信這就是爲什麼xml-to-object分析在使用這個庫時的行爲不同。因此,我得到

<ns0:SyncToken/> 

,而不是預期

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

似乎CakePHP的,其定義的String類,運行與IPP PHP SDK衝突局勢。

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

我認爲這個問題是更清晰了,有什麼建議的解決方案:這種相互矛盾的情況下,可以通過添加以下行到樣品CustomerUpdate.php腳本重新創建?

+1

您是否從FindByID調用獲取synctoken? –

+0

是的,我從FindById調用獲取synctoken(請參閱編輯1) – EricC

回答

0

對不起,如果我的迴應來得遲。我遇到了與Eric完全相同的問題,非常感謝您指向/Dependencies/XDS2PHP/src/com/mikebevz/xsd2php/Bind.php文件的方向。

我已經爲這個實現的解決方法是,以測試一個控制器對象的存在(存在於cakephp中環境)

我結束了更換此:

if (!class_exists($class_name)) { 

隨着:

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

現在dataService-> Update調用按預期工作。

+0

是的,這是有道理的。除了字符串之外,還可以測試Controller類的存在,使其更清楚cakephp上下文。 – EricC

2

您可以使用添加使您的代碼工作。

$ipp_customer = $dataService->FindById(
    new IPPCustomer(array('Id' => '6'), true) 
); 

$ipp_customer->DisplayName = 'Name Name Something'; 
$dataService->Add($ipp_customer); 

這在我的QuickBooks設置中成功更新了ID爲6的用戶的顯示名稱。它也應該爲你工作。

+0

我接受您的觀點。當我將示例代碼作爲獨立腳本運行時,它確實有效。我的Edit2爲我面臨的問題添加了更多細節和上下文。謝謝。 – EricC

+0

你是一個拯救生命的人,誰會猜到你'加'來更新... –

相關問題