Consolibyte Quickbooks PHP Web 连接器无法同步所有供应商

Consolibyte Quickbooks PHP web connector cannot sync all vendors

我希望将所有 Quickbooks 供应商同步到我的 Web 应用程序,但是我 运行 遇到了一个问题,我只能得到 10 个结果(不是我需要的 5500 个)它发送请求到 QWC,返回 10 个请求,然后 运行s 再次获取自上次 运行(秒前)以来更新的请求,而不是继续同步其余供应商。我确定我错过了一些重要的东西。我知道它一次同步 10 个,但它不应该继续一次同步 10 个,直到没有更多可同步为止吗?

我的代码主要基于这个例子:https://github.com/consolibyte/quickbooks-php/blob/master/docs/web_connector/example_web_connector_import.php

以下是一些代码片段:

Quickbooks 处理控制器 - 索引方法处理 QB 请求。供应商函数单独存储并在下面列出。

<?php


define('QB_QUICKBOOKS_CONFIG_LAST', 'last');
define('QB_QUICKBOOKS_CONFIG_CURR', 'curr');
define('QB_QUICKBOOKS_MAX_RETURNED', 10);
define('QB_QUICKBOOKS_MAILTO', '...');

class QuickbooksController extends Controller {

    public function index() {
        QuickBooks_WebConnector_Queue_Singleton::initialize($this->dsn);
        $queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
        $queue->enqueue(QUICKBOOKS_IMPORT_VENDOR, 1, QB_PRIORITY_VENDOR);
        $server = new QuickBooks_WebConnector_Server($this->dsn, $this->map, $this->errmap, $this->hooks, $this->log_level, $this->soapserver, QUICKBOOKS_WSDL, $this->soap_options, $this->handler_options, $this->driver_options, $this->callback_options);
        $response = $server->handle(true, true);
    }


    public function __construct() {
        $this->loadHelper('accounting.quickbooks.vendors');
        date_default_timezone_set('America/New_York');
        $this->user = 'internal';
        $this->pass = 'BrownBadgerPizza';

        $this->map = [
            QUICKBOOKS_IMPORT_VENDOR => array( 'vendorImportRequest', 'vendorImportResponse' ),
        ];
        $this->errmap = [
            500 => '_quickbooks_handle_500',
        ];
        $this->hooks = array(
            QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS => '_quickbooks_hook_loginsuccess',
        );
        $this->log_level = QUICKBOOKS_LOG_DEBUG;
        $this->soapserver = QUICKBOOKS_SOAPSERVER_BUILTIN;
        $this->handler_options = [
            'deny_concurrent_logins' => false,
            'deny_reallyfast_logins' => false,
        ];
        $this->driver_options = [];
        $this->callback_options = [];
        $this->dsn = '...',
        define('QB_QUICKBOOKS_DSN', $this->dsn);
    }

    public function support() {
        header("HTTP/1.1 200 OK");
    }
}

function _quickbooks_hook_loginsuccess($requestID, $user, $hook, &$err, $hook_data, $callback_config) {
    $Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
    $date = '1983-01-02 12:01:01';
    if (!_quickbooks_get_last_run($user, QUICKBOOKS_IMPORT_VENDOR))
    {
        _quickbooks_set_last_run($user, QUICKBOOKS_IMPORT_VENDOR, $date);
    }
    $Queue->enqueue(QUICKBOOKS_IMPORT_VENDOR, 1, QB_PRIORITY_VENDOR);
}

function _quickbooks_get_last_run($user, $action) {
    $type = null;
    $opts = null;
    return QuickBooks_Utilities::configRead(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_LAST . '-' . $action, $type, $opts);
}


function _quickbooks_set_last_run($user, $action, $force = null) {
    $value = date('Y-m-d') . 'T' . date('H:i:s');
    if ($force) {
        $value = date('Y-m-d', strtotime($force)) . 'T' . date('H:i:s', strtotime($force));
    }
    return QuickBooks_Utilities::configWrite(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_LAST . '-' . $action, $value);
}

function _quickbooks_get_current_run($user, $action)
{
    $type = null;
    $opts = null;
    return QuickBooks_Utilities::configRead(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_CURR . '-' . $action, $type, $opts);
}

function _quickbooks_set_current_run($user, $action, $force = null)
{
    $value = date('Y-m-d') . 'T' . date('H:i:s');

    if ($force)
    {
        $value = date('Y-m-d', strtotime($force)) . 'T' . date('H:i:s', strtotime($force));
    }

    return QuickBooks_Utilities::configWrite(QB_QUICKBOOKS_DSN, $user, md5(__FILE__), QB_QUICKBOOKS_CONFIG_CURR . '-' . $action, $value);
}

function _quickbooks_handle_500($requestID, $user, $action, $ID, $extra, &$err, $xml, $errnum, $errmsg) {
    return true;
}

供应商请求:

function vendorImportRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale) {
    $attr_iteratorID = '';
    $attr_iterator = ' iterator="Start" ';
    if (empty($extra['iteratorID'])) {
        $last = _quickbooks_get_last_run($user, $action);
        _quickbooks_set_last_run($user, $action);
        _quickbooks_set_current_run($user, $action, $last);
    } else {
        $attr_iteratorID = ' iteratorID="' . $extra['iteratorID'] . '" ';
        $attr_iterator = ' iterator="Continue" ';
        $last = _quickbooks_get_current_run($user, $action);
    }
    $xml = '<?xml version="1.0" encoding="utf-8"?>
        <?qbxml version="' . $version . '"?>
        <QBXML>
            <QBXMLMsgsRq onError="stopOnError">
                <VendorQueryRq ' . $attr_iterator . ' ' . $attr_iteratorID . ' requestID="' . $requestID . '">
                    <MaxReturned>' . QB_QUICKBOOKS_MAX_RETURNED . '</MaxReturned>
                    <FromModifiedDate>' . $last . '</FromModifiedDate>
                    <OwnerID>0</OwnerID>
                </VendorQueryRq>
            </QBXMLMsgsRq>
        </QBXML>';
    return $xml;
}

供应商回复:

function vendorImportResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents) {
    if (!empty($idents['iteratorRemainingCount'])) {
        $Queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
        $Queue->enqueue(QUICKBOOKS_IMPORT_VENDOR, null, QB_PRIORITY_VENDOR, array( 'iteratorID' => $idents['iteratorID'] ));
    }
... do things with XML

非常感谢您的帮助。

编辑:

quickbooks_queue table 第一次尝试同步所有供应商后的结果

qb_action    ident extra qbxml priority qb_status enqueue_datetime      dequeue_datetime      msg
VendorImport             1     4        e         2017-02-03 13:15:34   2017-02-03 13:15:341: A query request did not find a matching object in QuickBooks
VendorImport             1     4        q         2017-02-03 13:15:38   NULL

quickbooks_log table

Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
sendRequestXML()
Dequeued: ( VendorImport, 1 )
Outgoing XML request: <?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<VendorQueryRq  iterator="Start"   requestID="318">
<MaxReturned>10</MaxReturned>
<FromModifiedDate></FromModifiedDate>
<OwnerID>0</OwnerID>
</VendorQueryRq>
</QBXMLMsgsRq>
</QBXML>
Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
receiveResponseXML()
Incoming XML response:
10 vendors of data ...
25% complete...
Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
sendRequestXML()
Dequeued: ( VendorImport, 1 )
Outgoing XML request: <?xml version="1.0" encoding="utf-8"?>
<?qbxml version="13.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<VendorQueryRq  iterator="Start"   requestID="1">
<MaxReturned>10</MaxReturned>
<FromModifiedDate>2017-02-03T13:15:32</FromModifiedDate>
<OwnerID>0</OwnerID>
</VendorQueryRq>
</QBXMLMsgsRq>
</QBXML>
Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
receiveResponseXML()
Incoming XML response: <?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs>
<VendorQueryRs requestID="1" statusCode="1" statusSeverity="Info" statusMessage="A query request did not find a matching object in QuickBooks" iteratorRemainingCount="0" iteratorID="{a7b4ed15-9612-4fe8-aa3c-31ee60b7b491}" />
</QBXMLMsgsRs>
</QBXML>
Attempting to handle error: 1, A query request did not find a matching object in QuickBooks
Handled error: 1: A query request did not find a matching object in QuickBooks (handler returned: )
Transaction error at -1% complete...
Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
getLastError()
Handler is starting up...: Array
(
   [qb_company_file] => 
   [qbwc_min_version] => 
   [qbwc_wait_before_next_update] => 
   [qbwc_min_run_every_n_seconds] => 
   [qbwc_version_warning_message] => 
   [qbwc_version_error_message] => 
   [qbwc_interactive_url] => 
   [autoadd_missing_requestid] => 1
   [check_valid_requestid] => 1
   [server_version] => PHP QuickBooks SOAP Server v3.0 at /route.php/quickbooks
   [authenticate] => 
   [authenticate_dsn] => 
   [map_application_identifiers] => 1
   [allow_remote_addr] => Array
       (
       )

   [deny_remote_addr] => Array
       (
       )

   [convert_unix_newlines] => 1
   [deny_concurrent_logins] => 
   [deny_concurrent_timeout] => 60
   [deny_reallyfast_logins] => 
   [deny_reallyfast_timeout] => 600
   [masking] => 1
)
closeConnection()

编辑 #2 查看日志和队列后,我看到的是,即使我在收到 XML 响应时传递了 iteratorID,但由于某种原因,库没有通过排队请求的 $extra 参数传递该 ID。

数据库中的队列 table 在 extra 列中有这个:a:1:{s:10:"iteratorID";s:38:"{3a096324-6e5e-4fcb-a6ac-9a2600372029}";}。但是请求函数上的额外参数是空白的。

什么是 QB_QUICKBOOKS_MAX_RETURNED 值?

完成第 1 遍后,您是否获取返回的 Iterator 值并对其进行处理?

这可能是您的问题:

<FromModifiedDate></FromModifiedDate>

里面没有日期。

您确实 post 没有足够的代码让我们无法帮助您。

解决方案

我发现在我的 QBWC 处理函数中,我正在排队供应商导入请求。这是对登录成功排队的补充。我把它去掉后,它工作得很好。

这是使它起作用的更新:

来自

public function index() {
    QuickBooks_WebConnector_Queue_Singleton::initialize($this->dsn);
    $queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
    $queue->enqueue(QUICKBOOKS_IMPORT_VENDOR, 1, QB_PRIORITY_VENDOR);
    $server = new QuickBooks_WebConnector_Server($this->dsn, $this->map, $this->errmap, $this->hooks, $this->log_level, $this->soapserver, QUICKBOOKS_WSDL, $this->soap_options, $this->handler_options, $this->driver_options, $this->callback_options);
    $response = $server->handle(true, true);
}

public function index() {
    QuickBooks_WebConnector_Queue_Singleton::initialize($this->dsn);
    $queue = QuickBooks_WebConnector_Queue_Singleton::getInstance();
    $server = new QuickBooks_WebConnector_Server($this->dsn, $this->map, $this->errmap, $this->hooks, $this->log_level, $this->soapserver, QUICKBOOKS_WSDL, $this->soap_options, $this->handler_options, $this->driver_options, $this->callback_options);
    $response = $server->handle(true, true);
}