<?php require_once '../../QuickBooks.php'; $out = QuickBooks_Utilities::actionToObject('VendorCreditAdd'); print "\n\n" . $out . "\n\n"; //$out = QuickBooks_Utilities::actionToObject('VendorAdd'); //print("\n\n" . $out . "\n\n"); //print_r(QuickBooks_Utilities::listObjects());
/** * ReceiveResponseXML() method for the QuickBooks Web Connector - Receive and handle a resonse form QuickBooks * * The stdClass object passed as a parameter will have the following members: * - ->ticket The QuickBooks Web Connector ticket * - ->response An XML response message * - ->hresult Error code * - ->message Error message * * The sole data member of the returned object should be an integer. * - The data member should be -1 if an error occured and QBWC should call ->getLastError() * - Should be an integer 0 <= x < 100 to indicate success *and* that the application should continue to call ->sendRequestXML() at least one more time (more queued items still in the queue, the integer represents the percentage complete the total batch job is) * - Should be 100 to indicate success *and* that the queue has been exhausted * * The following user-defined hooks are invoked: * - QUICKBOOKS_HANDLERS_HOOK_RECEIVERESPONSEXML * * @param stdClass $obj * @return QuickBooks_Result_ReceiveResponseXML */ public function receiveResponseXML($obj) { $this->_driver->log('receiveResponseXML()', $obj->ticket, QUICKBOOKS_LOG_VERBOSE); if ($this->_driver->authCheck($obj->ticket)) { $user = $this->_driver->authResolve($obj->ticket); $hookdata = array('username' => $user, 'ticket' => $obj->ticket); $hookerr = ''; $this->_callHook($obj->ticket, QUICKBOOKS_HANDLERS_HOOK_RECEIVERESPONSEXML, null, null, null, null, $hookerr, null, array(), $hookdata); $this->_driver->log('Incoming XML response: ' . $obj->response, $obj->ticket, QUICKBOOKS_LOG_DEBUG); // Check if we got a error message... if (strlen($obj->message) or $this->_extractStatusCode($obj->response)) { if ($requestID = $this->_extractRequestID($obj->response)) { $errnum = $this->_extractStatusCode($obj->response); //$action = current(explode('|', $requestID)); //$ident = next(explode('|', $requestID)); $action = ''; $ident = ''; $this->_parseRequestID($requestID, $action, $ident); // Fetch the request that was processed and EXPERIENCED AN ERROR! $extra = ''; if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING)) { if ($current['extra']) { $extra = unserialize($current['extra']); } } if ($obj->message) { $errmsg = $obj->message; } else { if ($status = $this->_extractStatusMessage($obj->response)) { $errmsg = $status; } } $errerr = ''; $continue = $this->_handleError($obj->ticket, $errnum, $errmsg, $requestID, $action, $ident, $extra, $errerr, $obj->response, array()); // $errnum, $errmsg, $requestID, $action, $ident, $extra, &$err, $xml, $qb_identifiers = array() if ($errerr) { // The error handler returned an error too... $this->_driver->log('An error occured while handling quickbooks error ' . $errnum . ': ' . $errmsg . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL); } } else { $errerr = ''; $continue = $this->_handleError($obj->ticket, $obj->hresult, $obj->message, null, null, null, null, $errerr, $obj->response, array()); if ($errerr) { // The error handler returned an error too... $this->_driver->log('An error occured while handling generic error ' . $obj->hresult . ': ' . $obj->message . ': ' . $errerr, $obj->ticket, QUICKBOOKS_LOG_NORMAL); } } // Calculate the percentage done $progress = $this->_calculateProgress($obj->ticket); if (!$continue) { $progress = -1; } $this->_driver->log('Transaction error at ' . $progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE); return new QuickBooks_Result_ReceiveResponseXML($progress); } $action = null; $ident = null; $requestID = null; if ($requestID = $this->_extractRequestID($obj->response)) { //$action = current(explode('|', $requestID)); //$ident = end(explode('|', $requestID)); $action = ''; $ident = ''; $this->_parseRequestID($requestID, $action, $ident); // Fetch the request that's being processed $extra = ''; if ($current = $this->_driver->queueFetch($user, $action, $ident, QUICKBOOKS_STATUS_PROCESSING)) { if ($current['extra']) { $extra = unserialize($current['extra']); } } // Update the status to success (no error occured) $this->_driver->queueStatus($obj->ticket, $action, $ident, QUICKBOOKS_STATUS_SUCCESS); } // Extract ListID, TxnID, etc. from the response $identifiers = $this->_extractIdentifiers($obj->response); //$this->_driver->log(var_export($identifiers, true), $obj->ticket, QUICKBOOKS_LOG_VERBOSE); // Auto-map $ident unique identifier from web application to the QuickBooks ListID or TxnID if ($this->_config['map_application_identifiers']) { $adds = QuickBooks_Utilities::listActions('*Add*'); $mods = QuickBooks_Utilities::listActions('*Mod*'); $qbkey = QuickBooks_Utilities::keyForAction($action); $type = QuickBooks_Utilities::actionToObject($action); $EditSequence = ''; if (isset($identifiers['EditSequence'])) { $EditSequence = $identifiers['EditSequence']; } if (in_array($action, $adds) and isset($identifiers[$qbkey]) and $type) { // Try to map the $ident to the QuickBooks identifier $this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence); } else { if (in_array($action, $mods) and isset($identifiers[$qbkey]) and $type) { // Try to map the $ident to the QuickBooks identifier $this->_driver->identMap($user, $type, $ident, $identifiers[$qbkey], $EditSequence); } } } $err = null; $last_action_time = $this->_driver->queueActionLast($user, $action); $last_actionident_time = $this->_driver->queueActionIdentLast($user, $action, $ident); $this->_callMappedFunction(1, $user, $action, $ident, $extra, $err, $last_action_time, $last_actionident_time, $obj->response, $identifiers); // Calculate the percentage done $progress = $this->_calculateProgress($obj->ticket); if ($err) { $errerr = ''; $continue = $this->_handleError($obj->ticket, QUICKBOOKS_ERROR_HANDLER, $err, $requestID, $action, $ident, $extra, $errerr, $obj->response, $identifiers); if (!$continue) { $progress = -1; } } $this->_driver->log($progress . '% complete... ', $obj->ticket, QUICKBOOKS_LOG_VERBOSE); return new QuickBooks_Result_ReceiveResponseXML($progress); } return new QuickBooks_Result_ReceiveResponseXML(-1); }
/** * Converts an action to the corresponding Mod Action * Ex: Customer to CustomerQuery */ public static function convertActionToMod($action) { return QuickBooks_Utilities::objectToMod(QuickBooks_Utilities::actionToObject($action)); }
/** * Restrict the queueing maps to "only do these actions" and "dont do these actions" maps * * @param array $action_to_priority * @param array $only_do * @param array $dont_do * @return array */ protected static function _filterActions($action_to_priority, $only_do, $dont_do, $type) { $start = microtime(true); foreach ($action_to_priority as $action => $priority) { //print('stepping 1... [' . (microtime(true) - $start) . ']' . "\n"); $converted = QuickBooks_Utilities::actionToObject($action); //print('stepping 2... [' . (microtime(true) - $start) . ']' . "\n"); if (count($only_do) and (false === array_search($action, $only_do) and false === array_search($converted, $only_do))) { unset($action_to_priority[$action]); } if (count($dont_do) and (false !== array_search($action, $dont_do) or false !== array_search($converted, $dont_do))) { unset($action_to_priority[$action]); } } //print("\n" . 'ending... [' . (microtime(true) - $start) . ']' . "\n\n"); arsort($action_to_priority); //print_r($action_to_priority); return $action_to_priority; }
/** * Restrict the queueing maps to "only do these actions" and "dont do these actions" maps * * @param array $action_to_priority * @param array $only_do * @param array $dont_do * @return array */ protected static function _filterActions($action_to_priority, $only_do, $dont_do, $type) { //print_r($action_to_priority); foreach ($action_to_priority as $action => $priority) { $converted = ''; /* switch ($type) { case QUICKBOOKS_ADD: $converted = QuickBooks_Utilities::objectToAdd($action); break; case QUICKBOOKS_MOD: $converted = QuickBooks_Utilities::objectToMod($action); break; case QUICKBOOKS_QUERY: $converted = QuickBooks_Utilities::objectToQuery($action); break; case QUICKBOOKS_DELETE: $converted = QuickBooks_Utilities::objectToDelete($action); break; } */ $converted = QuickBooks_Utilities::actionToObject($action); //print('searching for: ' . $action . ' or ' . $converted . "\n"); if (count($only_do) and (false === array_search($action, $only_do) and false === array_search($converted, $only_do))) { unset($action_to_priority[$action]); } if (count($dont_do) and (false !== array_search($action, $dont_do) or false !== array_search($converted, $dont_do))) { unset($action_to_priority[$action]); } } //print_r($action_to_priority); //exit; return $action_to_priority; }
/** * Convert a QuickBooks_XML_Node object to a QuickBooks_Object_* object instance * * @param QuickBooks_XML_Node $XML * @param string $action_or_object * @return QuickBooks_Object */ public static function fromXML($XML, $action_or_object = null) { if (!$action_or_object or $action_or_object == QUICKBOOKS_QUERY_ITEM) { $action_or_object = $XML->name(); } $type = QuickBooks_Utilities::actionToObject($action_or_object); $exceptions = array(QUICKBOOKS_OBJECT_SERVICEITEM => 'ServiceItem', QUICKBOOKS_OBJECT_INVENTORYITEM => 'InventoryItem', QUICKBOOKS_OBJECT_NONINVENTORYITEM => 'NonInventoryItem', QUICKBOOKS_OBJECT_DISCOUNTITEM => 'DiscountItem', QUICKBOOKS_OBJECT_FIXEDASSETITEM => 'FixedAssetItem', QUICKBOOKS_OBJECT_GROUPITEM => 'GroupItem', QUICKBOOKS_OBJECT_OTHERCHARGEITEM => 'OtherChargeItem', QUICKBOOKS_OBJECT_SALESTAXITEM => 'SalesTaxItem', QUICKBOOKS_OBJECT_SALESTAXGROUPITEM => 'SalesTaxGroupItem', QUICKBOOKS_OBJECT_SUBTOTALITEM => 'SubtotalItem', QUICKBOOKS_OBJECT_INVENTORYASSEMBLYITEM => 'InventoryAssemblyItem'); if (isset($exceptions[$type])) { $type = $exceptions[$type]; } //print('trying to create type: {' . $type . '}' . "\n"); $class = 'QuickBooks_QBXML_Object_' . ucfirst(strtolower($type)); if (true) { $Object = QuickBooks_QBXML_Object::_fromXMLHelper($class, $XML); if (!is_object($Object)) { return false; } $children = array(); switch ($Object->object()) { case QUICKBOOKS_OBJECT_RECEIVEPAYMENT: $children = array('AppliedToTxnRet' => array('QuickBooks_QBXML_Object_ReceivePayment_AppliedToTxn', 'addAppliedToTxn')); break; case QUICKBOOKS_OBJECT_BILL: $children = array('ItemLineRet' => array('QuickBooks_QBXML_Object_Bill_ItemLine', 'addItemLine'), 'ExpenseLineRet' => array('QuickBooks_QBXML_Object_Bill_ExpenseLine', 'addExpenseLine')); break; case QUICKBOOKS_OBJECT_PURCHASEORDER: $children = array('PurchaseOrderLineRet' => array('QuickBooks_QBXML_Object_PurchaseOrder_PurchaseOrderLine', 'addPurchaseOrderLine')); break; case QUICKBOOKS_OBJECT_INVOICE: $children = array('InvoiceLineRet' => array('QuickBooks_QBXML_Object_Invoice_InvoiceLine', 'addInvoiceLine')); break; case QUICKBOOKS_OBJECT_ESTIMATE: $children = array('EstimateLineRet' => array('QuickBooks_QBXML_Object_Estimate_EstimateLine', 'addEstimateLine')); break; case QUICKBOOKS_OBJECT_SALESRECEIPT: $children = array('SalesReceiptLineRet' => array('QuickBooks_QBXML_Object_SalesReceipt_SalesReceiptLine', 'addSalesReceiptLine')); break; case QUICKBOOKS_OBJECT_JOURNALENTRY: $children = array('JournalCreditLineRet' => array('QuickBooks_QBXML_Object_JournalEntry_JournalCreditLine', 'addCreditLine'), 'JournalDebitLineRet' => array('QuickBooks_QBXML_Object_JournalEntry_JournalDebitLine', 'addDebitLine')); break; case QUICKBOOKS_OBJECT_SALESTAXGROUPITEM: $children = array('ItemSalesTaxRef' => array('QuickBooks_QBXML_Object_SalesTaxGroupItem_ItemSalesTaxRef', 'addItemSalesTaxRef')); break; case QUICKBOOKS_OBJECT_UNITOFMEASURESET: $children = array('RelatedUnit' => array('QuickBooks_QBXML_Object_UnitOfMeasureSet_RelatedUnit', 'addRelatedUnit'), 'DefaultUnit' => array('QuickBooks_QBXML_Object_UnitOfMeasureSet_DefaultUnit', 'addDefaultUnit')); break; } foreach ($children as $node => $tmp) { $childclass = $tmp[0]; $childmethod = $tmp[1]; if (class_exists($childclass)) { foreach ($XML->children() as $ChildXML) { if ($ChildXML->name() == $node) { $ChildObject = QuickBooks_QBXML_Object::_fromXMLHelper($childclass, $ChildXML); $Object->{$childmethod}($ChildObject); } } } else { print 'Missing class: ' . $childclass . "\n"; } } return $Object; } return false; }
/** * Convert a QuickBooks_XML_Node object to a QuickBooks_Object_* object instance * * @param QuickBooks_XML_Node $XML * @param string $action_or_object * @return QuickBooks_Object */ public static function fromXML($XML, $action_or_object = null) { if (!$action_or_object) { $action_or_object = $XML->name(); } $type = QuickBooks_Utilities::actionToObject($action_or_object); $class = 'QuickBooks_Object_' . ucfirst(strtolower($type)); if (class_exists($class)) { $Object = QuickBooks_Object::_fromXMLHelper($class, $XML); $children = array(); switch ($Object->object()) { case QUICKBOOKS_OBJECT_PURCHASEORDER: $children = array('PurchaseOrderLineRet' => array('QuickBooks_Object_PurchaseOrder_PurchaseOrderLine', 'addPurchaseOrderLine')); break; case QUICKBOOKS_OBJECT_INVOICE: $children = array('InvoiceLineRet' => array('QuickBooks_Object_Invoice_InvoiceLine', 'addInvoiceLine')); break; case QUICKBOOKS_OBJECT_ESTIMATE: $children = array('EstimateLineRet' => array('QuickBooks_Object_Estimate_EstimateLine', 'addEstimateLine')); break; case QUICKBOOKS_OBJECT_SALESRECEIPT: $children = array('SalesReceiptLineRet' => array('QuickBooks_Object_SalesReceipt_SalesReceiptLine', 'addSalesReceiptLine')); break; case QUICKBOOKS_OBJECT_JOURNALENTRY: $children = array('JournalCreditLine' => array('QuickBooks_Object_JournalEntry_JournalCreditLine', 'addCreditLine'), 'JournalDebitLine' => array('QuickBooks_Object_JournalEntry_JournalDebitLine', 'addDebitLine')); break; } foreach ($children as $node => $tmp) { $childclass = $tmp[0]; $childmethod = $tmp[1]; if (class_exists($childclass)) { foreach ($XML->children() as $ChildXML) { if ($ChildXML->name() == $node) { $ChildObject = QuickBooks_Object::_fromXMLHelper($childclass, $ChildXML); $Object->{$childmethod}($ChildObject); } } } } return $Object; } return false; }
/** * * * */ protected function &_createForMirror($mode, $user, $date_from, $date_to, $fetch_full_record, $restrict) { $Driver = $this->_driver; $report = array(); $do_restrict = count($restrict) > 0; $actions = QuickBooks_Utilities::listActions('*IMPORT*'); //print_r($actions); //print_r($restrict); foreach ($actions as $action) { $object = QuickBooks_Utilities::actionToObject($action); //print('checking object [' . $object . ']' . "<br />"); if ($do_restrict and !in_array($object, $restrict)) { continue; } //print('doing object: ' . $object . '<br />'); $pretty = $this->_prettyName($object); $report[$pretty] = array(); QuickBooks_SQL_Schema::mapPrimaryKey($object, QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $table_and_field); //print_r($table_and_field); if (!empty($table_and_field[0]) and !empty($table_and_field[1])) { $sql = "\n\t\t\t\t\tSELECT \n\t\t\t\t\t\t*\n\t\t\t\t\tFROM \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . $table_and_field[0] . " \n\t\t\t\t\tWHERE "; if ($mode == QuickBooks_Status_Report::MODE_MIRROR_ERRORS) { $sql .= " LENGTH(" . QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER . ") > 0 "; } else { $sql .= " 1 "; } if ($timestamp = strtotime($date_from) and $timestamp > 0) { $sql .= " AND TimeCreated >= '" . date('Y-m-d H:i:s', $timestamp) . "' "; } if ($timestamp = strtotime($date_to) and $timestamp > 0) { $sql .= " AND TimeCreated <= '" . date('Y-m-d H:i:s', $timestamp) . "' "; } $sql .= " ORDER BY qbsql_id DESC "; //print($sql); $errnum = 0; $errmsg = ''; $res = $Driver->query($sql, $errnum, $errmsg); while ($arr = $Driver->fetch($res)) { $record = null; if ($fetch_full_record) { $record = $arr; } if ($arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER]) { $details = QuickBooks_Status_Report::describe($arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER], $arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_MESSAGE]); } else { if ($arr[QUICKBOOKS_DRIVER_SQL_FIELD_RESYNC] == $arr[QUICKBOOKS_DRIVER_SQL_FIELD_MODIFY]) { $details = 'Synced successfully.'; } else { if ($arr[QUICKBOOKS_DRIVER_SQL_FIELD_MODIFY] > $arr[QUICKBOOKS_DRIVER_SQL_FIELD_RESYNC]) { $details = 'Waiting to sync.'; } } } $report[$pretty][] = array($arr[QUICKBOOKS_DRIVER_SQL_FIELD_ID], $this->_fetchSomeField($arr, array('ListID', 'TxnID')), $this->_fetchSomeField($arr, array('FullName', 'Name', 'RefNumber')), $this->_fetchSomeField($arr, array('TxnDate')), $this->_fetchSomeField($arr, array('Customer_FullName', 'Vendor_FullName')), $arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER], $arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_MESSAGE], $details, $arr[QUICKBOOKS_DRIVER_SQL_FIELD_DEQUEUE_TIME], $record); } } } return $report; }
public function adds($adds = array(), $mark_as_queued = true, $limit = null) { $Driver = $this->_driver; $NOW = date('Y-m-d H:i:s'); $sql_add = $adds; $list = array(); //$Driver->log('Input is: ' . print_r($adds, true)); // Check if any objects need to be pushed back to QuickBooks foreach ($sql_add as $action => $priority) { $object = QuickBooks_Utilities::actionToObject($action); //$Driver->log('Action is: ' . $action . ', object is: ' . $object); $table_and_field = array(); // Convert to table and primary key, select qbsql id QuickBooks_SQL_Schema::mapPrimaryKey($object, QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $table_and_field); $Driver->log('Searching table: ' . print_r($table_and_field, true) . ' for ADDED records.'); //print_r($table_and_field); if (!empty($table_and_field[0]) and !empty($table_and_field[1])) { // For ADDs // - Do not sync if to_skip = 1 // - Do not sync if to_delete = 1 // - Do not sync if last_errnum is not empty @TODO Implement this switch ($table_and_field[0]) { case 'customer': $priority_reduce = 'Parent_FullName'; break; default: $priority_reduce = null; } $extras = ''; if ($priority_reduce) { $extras = ', ' . $priority_reduce; } $sql = "\n\t\t\t\t\tSELECT \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_ID . ", \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER . " " . $extras . "\n\t\t\t\t\tFROM \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . $table_and_field[0] . " \n\t\t\t\t\tWHERE \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_MODIFY . " IS NOT NULL AND \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_RESYNC . " IS NULL AND \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_TO_SKIP . " != 1 AND \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_TO_DELETE . " != 1 AND \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_FLAG_DELETED . " != 1 AND \n\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_MODIFY . " <= '" . $NOW . "' "; // " . QUICKBOOKS_DRIVER_SQL_FLAG_TO_VOID . " != 1 "; //$Driver->log($sql); $errnum = 0; $errmsg = ''; $count = 0; $res = $Driver->query($sql, $errnum, $errmsg); while ($arr = $Driver->fetch($res)) { if (strlen($arr[QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER])) { continue; } if (!isset($list[$action])) { $list[$action] = array(); } $tmp_priority = $priority; if ($priority_reduce and isset($arr[$priority_reduce]) and !empty($arr[$priority_reduce])) { $tmp_priority = $priority - 1; } $list[$action][$arr[QUICKBOOKS_DRIVER_SQL_FIELD_ID]] = $tmp_priority; $count++; if ($mark_as_queued) { // Make the record as having been ->enqueue()d $errnum = 0; $errmsg = ''; $Driver->query("\n\t\t\t\t\t\t\tUPDATE \n\t\t\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . $table_and_field[0] . " \n\t\t\t\t\t\t\tSET \n\t\t\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_ENQUEUE_TIME . " = '" . date('Y-m-d H:i:s') . "'\n\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_FIELD_ID . " = " . $arr[QUICKBOOKS_DRIVER_SQL_FIELD_ID], $errnum, $errmsg); } /* if (count($list[$action]) >= $limit) { break; } */ if ($limit > 0 and $count >= $limit) { break 2; } } } } return $list; }