示例#1
0
文件: API.php 项目: Edgargm87/efapcom
 /**
  * Guess the appropriate priority for an action
  * 
  * @param string $action		The action to guess for
  * @param string $dependency	A dependency (i.e. a DataExtAdd that depends on a CustomerAdd)
  * @return integer				The best guess at the proper priority
  */
 public static function priority($action, $dependency = null)
 {
     return QuickBooks_Utilities::priorityForAction($action, $dependency);
 }
示例#2
0
 /**
  * 
  * 
  */
 protected static function _triggerActions($user, $table, $Object, $action = null)
 {
     $Driver = QuickBooks_Driver_Singleton::getInstance();
     // Be *CAREFUL* here, you don't want to trigger an infinite loop of
     //	high-priority Query requests! i.e.:
     //	ReceivePayment_AppliedToTxn requests an InvoiceQuery
     //	Invoice_LinkedTxn requests a ReceivePaymentQuery
     //	ReceivePayment_AppliedToTxn requests an InvoiceQuery
     //	... wash rinse repeat
     $priority = 9999;
     if ($action) {
         $priority = QuickBooks_Utilities::priorityForAction($action) - 1;
     }
     // Account. 	Balance, TotalBalance
     // Bill. 		IsPaid, OpenAmount, AmountDue
     // Charge. 		BalanceRemaining
     // CreditMemo.	IsPending, CreditRemaining
     // Customer.	Balance, TotalBalance,
     // Invoice.		IsPending, AppliedAmount, BalanceRemaining, IsPaid
     //$Driver->log('Running triggered actions for: [' . $table . ']', null, QUICKBOOKS_LOG_DEBUG);
     switch (strtolower($table)) {
         case 'receivepayment_appliedtotxn':
             // Fetch the linked invoice
             $where = array('TxnID' => $Object->get('ToTxnID'));
             // @todo WARNING WARNING WARNING THIS DOES NOT WORK, I DONT KNOW WHY!
             /*
             if ($Object->get('TxnType') == 'Invoice' and 
             	$arr = $Driver->get(QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . 'invoice', $where))
             {
             	$Driver->log('Running triggered actions: derive invoice, derive customer', null, QUICKBOOKS_LOG_DEBUG);
             	
             	// Fetch the derived fields from the invoice, because the invoice needs it's balance updated
             	$Driver->queueEnqueue($user, QUICKBOOKS_DERIVE_INVOICE, null, true, $priority, 
             		array( 'TxnID' => $arr['TxnID'] ) );
             	
             	// Fetch the derived fields from the customer, balance updated
             	$Driver->queueEnqueue($user, QUICKBOOKS_DERIVE_CUSTOMER, null, true, $priority, 
             		array( 'ListID' => $arr['Customer_ListID'] ) );
             }
             */
             break;
         case 'receivepayment':
         case 'invoice':
             // A customer has an updated invoice or payment, so the Customer Balance changed
             /*
             $Driver->log('Running triggered actions: derive customer', null, QUICKBOOKS_LOG_DEBUG);
             
             $Driver->queueEnqueue($user, QUICKBOOKS_DERIVE_CUSTOMER, null, true, $priority, 
             	array( 'ListID' => $Object->get('Customer_ListID') ) );
             */
             break;
         case 'bill':
         case 'billpaymentcheck':
         case 'billpaymentcreditcard':
             // We paid a bill, so the Vendor Balance has changed
             break;
     }
 }
 /**
  * 
  * 
  * 
  */
 public static function ItemInventoryAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents, $config = array())
 {
     $Driver = QuickBooks_Driver_Singleton::getInstance();
     $Parser = new QuickBooks_XML_Parser($xml);
     $errnum = 0;
     $errmsg = '';
     $Doc = $Parser->parse($errnum, $errmsg);
     $Root = $Doc->getRoot();
     $List = $Root->getChildAt('QBXML QBXMLMsgsRs ItemInventoryAddRs');
     $extra['IsAddResponse'] = true;
     QuickBooks_Server_SQL_Callbacks::_QueryResponse(QUICKBOOKS_OBJECT_INVENTORYITEM, $List, $requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents, $config);
     $Driver->queueEnqueue($user, QUICKBOOKS_QUERY_INVENTORYADJUSTMENT, md5(__FILE__), true, QuickBooks_Utilities::priorityForAction(QUICKBOOKS_QUERY_INVENTORYADJUSTMENT));
 }
示例#4
0
 /**
  * Try to guess the queueing priority for this action
  * 
  * @param string $action		The action you're trying to guess for
  * @param string $dependency	If the action depends on another action (i.e. a DataExtAdd for a CustomerAdd) you can pass the dependency here
  * @return integer				A best guess at the proper priority
  */
 public static function priorityForAction($action, $dependency = null)
 {
     // low priorities up here (*lots* of dependencies)
     static $priorities = array(QUICKBOOKS_DELETE_TRANSACTION, QUICKBOOKS_VOID_TRANSACTION, QUICKBOOKS_DEL_DATAEXT, QUICKBOOKS_MOD_DATAEXT, QUICKBOOKS_ADD_DATAEXT, QUICKBOOKS_MOD_JOURNALENTRY, QUICKBOOKS_ADD_JOURNALENTRY, QUICKBOOKS_MOD_RECEIVEPAYMENT, QUICKBOOKS_ADD_RECEIVEPAYMENT, QUICKBOOKS_MOD_BILLPAYMENTCHECK, QUICKBOOKS_ADD_BILLPAYMENTCHECK, QUICKBOOKS_ADD_BILLPAYMENTCREDITCARD, QUICKBOOKS_MOD_BILL, QUICKBOOKS_ADD_BILL, QUICKBOOKS_MOD_PURCHASEORDER, QUICKBOOKS_ADD_PURCHASEORDER, QUICKBOOKS_MOD_INVOICE, QUICKBOOKS_ADD_INVOICE, QUICKBOOKS_MOD_SALESORDER, QUICKBOOKS_ADD_SALESORDER, QUICKBOOKS_MOD_ESTIMATE, QUICKBOOKS_ADD_ESTIMATE, QUICKBOOKS_ADD_INVENTORYADJUSTMENT, QUICKBOOKS_ADD_CREDITMEMO, QUICKBOOKS_MOD_CREDITMEMO, QUICKBOOKS_ADD_ITEMRECEIPT, QUICKBOOKS_MOD_ITEMRECEIPT, QUICKBOOKS_MOD_SALESRECEIPT, QUICKBOOKS_ADD_SALESRECEIPT, QUICKBOOKS_ADD_SALESTAXITEM, QUICKBOOKS_MOD_SALESTAXITEM, QUICKBOOKS_ADD_DISCOUNTITEM, QUICKBOOKS_MOD_DISCOUNTITEM, QUICKBOOKS_ADD_OTHERCHARGEITEM, QUICKBOOKS_MOD_OTHERCHARGEITEM, QUICKBOOKS_MOD_NONINVENTORYITEM, QUICKBOOKS_ADD_NONINVENTORYITEM, QUICKBOOKS_MOD_INVENTORYITEM, QUICKBOOKS_ADD_INVENTORYITEM, QUICKBOOKS_MOD_INVENTORYASSEMBLYITEM, QUICKBOOKS_ADD_INVENTORYASSEMBLYITEM, QUICKBOOKS_MOD_SERVICEITEM, QUICKBOOKS_ADD_SERVICEITEM, QUICKBOOKS_MOD_PAYMENTITEM, QUICKBOOKS_ADD_PAYMENTITEM, QUICKBOOKS_MOD_SALESREP, QUICKBOOKS_ADD_SALESREP, QUICKBOOKS_MOD_EMPLOYEE, QUICKBOOKS_ADD_EMPLOYEE, QUICKBOOKS_ADD_SALESTAXCODE, QUICKBOOKS_MOD_VENDOR, QUICKBOOKS_ADD_VENDOR, QUICKBOOKS_MOD_CUSTOMER, QUICKBOOKS_ADD_CUSTOMER, QUICKBOOKS_MOD_ACCOUNT, QUICKBOOKS_ADD_ACCOUNT, QUICKBOOKS_ADD_CLASS, QUICKBOOKS_ADD_PAYMENTMETHOD, QUICKBOOKS_ADD_SHIPMETHOD, QUICKBOOKS_QUERY_PURCHASEORDER, QUICKBOOKS_QUERY_ITEMRECEIPT, QUICKBOOKS_QUERY_SALESORDER, QUICKBOOKS_QUERY_SALESRECEIPT, QUICKBOOKS_QUERY_INVOICE, QUICKBOOKS_QUERY_ESTIMATE, QUICKBOOKS_QUERY_RECEIVEPAYMENT, QUICKBOOKS_QUERY_CREDITMEMO, QUICKBOOKS_QUERY_BILLPAYMENTCHECK, QUICKBOOKS_QUERY_BILLPAYMENTCREDITCARD, QUICKBOOKS_QUERY_BILLTOPAY, QUICKBOOKS_QUERY_BILL, QUICKBOOKS_QUERY_CREDITCARDCHARGE, QUICKBOOKS_QUERY_CREDITCARDCREDIT, QUICKBOOKS_QUERY_CHECK, QUICKBOOKS_QUERY_CHARGE, QUICKBOOKS_QUERY_DELETEDLISTS, QUICKBOOKS_QUERY_DELETEDTXNS, QUICKBOOKS_QUERY_TIMETRACKING, QUICKBOOKS_QUERY_VENDORCREDIT, QUICKBOOKS_QUERY_INVENTORYADJUSTMENT, QUICKBOOKS_QUERY_ITEM, QUICKBOOKS_QUERY_DISCOUNTITEM, QUICKBOOKS_QUERY_SALESTAXITEM, QUICKBOOKS_QUERY_SERVICEITEM, QUICKBOOKS_QUERY_NONINVENTORYITEM, QUICKBOOKS_QUERY_INVENTORYITEM, QUICKBOOKS_QUERY_SALESREP, QUICKBOOKS_QUERY_VEHICLEMILEAGE, QUICKBOOKS_QUERY_VEHICLE, QUICKBOOKS_QUERY_CUSTOMER, QUICKBOOKS_QUERY_VENDOR, QUICKBOOKS_QUERY_EMPLOYEE, QUICKBOOKS_QUERY_WORKERSCOMPCODE, QUICKBOOKS_QUERY_UNITOFMEASURESET, QUICKBOOKS_QUERY_JOURNALENTRY, QUICKBOOKS_QUERY_DEPOSIT, QUICKBOOKS_QUERY_SHIPMETHOD, QUICKBOOKS_QUERY_PAYMENTMETHOD, QUICKBOOKS_QUERY_PRICELEVEL, QUICKBOOKS_QUERY_DATEDRIVENTERMS, QUICKBOOKS_QUERY_BILLINGRATE, QUICKBOOKS_QUERY_CUSTOMERTYPE, QUICKBOOKS_QUERY_CUSTOMERMSG, QUICKBOOKS_QUERY_TERMS, QUICKBOOKS_QUERY_SALESTAXCODE, QUICKBOOKS_QUERY_ACCOUNT, QUICKBOOKS_QUERY_CLASS, QUICKBOOKS_QUERY_JOBTYPE, QUICKBOOKS_QUERY_VENDORTYPE, QUICKBOOKS_QUERY_COMPANY, QUICKBOOKS_IMPORT_RECEIVEPAYMENT, QUICKBOOKS_IMPORT_PURCHASEORDER, QUICKBOOKS_IMPORT_ITEMRECEIPT, QUICKBOOKS_IMPORT_SALESRECEIPT, QUICKBOOKS_IMPORT_INVOICE, QUICKBOOKS_IMPORT_SALESORDER, QUICKBOOKS_IMPORT_ESTIMATE, QUICKBOOKS_IMPORT_BILLPAYMENTCHECK, QUICKBOOKS_IMPORT_BILLPAYMENTCREDITCARD, QUICKBOOKS_IMPORT_BILLTOPAY, QUICKBOOKS_IMPORT_BILL, QUICKBOOKS_IMPORT_CREDITCARDCHARGE, QUICKBOOKS_IMPORT_CREDITCARDCREDIT, QUICKBOOKS_IMPORT_CHECK, QUICKBOOKS_IMPORT_CHARGE, QUICKBOOKS_IMPORT_DELETEDLISTS, QUICKBOOKS_IMPORT_DELETEDTXNS, QUICKBOOKS_IMPORT_TIMETRACKING, QUICKBOOKS_IMPORT_VENDORCREDIT, QUICKBOOKS_IMPORT_INVENTORYADJUSTMENT, QUICKBOOKS_IMPORT_ITEM, QUICKBOOKS_IMPORT_DISCOUNTITEM, QUICKBOOKS_IMPORT_SALESTAXITEM, QUICKBOOKS_IMPORT_SERVICEITEM, QUICKBOOKS_IMPORT_NONINVENTORYITEM, QUICKBOOKS_IMPORT_INVENTORYITEM, QUICKBOOKS_IMPORT_INVENTORYASSEMBLYITEM, QUICKBOOKS_IMPORT_SALESREP, QUICKBOOKS_IMPORT_VEHICLEMILEAGE, QUICKBOOKS_IMPORT_VEHICLE, QUICKBOOKS_IMPORT_CUSTOMER, QUICKBOOKS_IMPORT_VENDOR, QUICKBOOKS_IMPORT_EMPLOYEE, QUICKBOOKS_IMPORT_WORKERSCOMPCODE, QUICKBOOKS_IMPORT_UNITOFMEASURESET, QUICKBOOKS_IMPORT_JOURNALENTRY, QUICKBOOKS_IMPORT_DEPOSIT, QUICKBOOKS_IMPORT_SHIPMETHOD, QUICKBOOKS_IMPORT_PAYMENTMETHOD, QUICKBOOKS_IMPORT_PRICELEVEL, QUICKBOOKS_IMPORT_DATEDRIVENTERMS, QUICKBOOKS_IMPORT_BILLINGRATE, QUICKBOOKS_IMPORT_CUSTOMERTYPE, QUICKBOOKS_IMPORT_CUSTOMERMSG, QUICKBOOKS_IMPORT_TERMS, QUICKBOOKS_IMPORT_SALESTAXCODE, QUICKBOOKS_IMPORT_ACCOUNT, QUICKBOOKS_IMPORT_CLASS, QUICKBOOKS_IMPORT_JOBTYPE, QUICKBOOKS_IMPORT_VENDORTYPE, QUICKBOOKS_IMPORT_COMPANY);
     // high priorities down here (no dependencies OR queries)
     // Now, let's space those priorities out a little bit, it gives us some
     //	wiggle room in case we need to add things inbetween the default
     //	priority values
     static $wiggled = false;
     $wiggle = 6;
     if (!$wiggled) {
         $count = count($priorities);
         for ($i = $count - 1; $i >= 0; $i--) {
             $priorities[$i * $wiggle] = $priorities[$i];
             unset($priorities[$i]);
             // with a wiggle multiplier of 2...
             // 	priority 25 goes to 50
             // 	priority 24 goes to 48
             // 	priority 23 goes to 46
             // 	etc. etc. etc.
         }
         $wiggled = true;
         //print_r($priorities);
     }
     if ($dependency) {
         //
         // This is a list of dependency modifications
         //	For instance, normally, you'd want to send just any  old DataExtAdd
         //	with a really low priority, because whatever record it applies to
         //	must be in QuickBooks before you send the DataExtAdd/Mod request.
         //
         //	However, if we pass in the $dependency of QUICKBOOKS_ADD_CUSTOMER,
         //	then we know that this DataExt applies to a CustomerAdd, and can
         //	therefore be sent with a priority *just barely lower than* than a
         //	CustomerAdd request, which will ensure this gets run as soon as
         //	possible, but not sooner than the CustomerAdd.
         //
         //	This is important because in some cases, this data will be
         //	automatically used by QuickBooks. For instance, a custom field that
         //	is placed on an Invoice *must already be populated for the
         //	Customer* before the invoice is created.
         //
         // This is an example of a priority list without dependencies, and it's bad:
         //	CustomerAdd, InvoiceAdd, DataExtAdd
         //	(the custom field for the customer doesn't get populated in the invoice)
         //
         // This is an example of a priority list with dependencies, and it's good:
         // 	CustomerAdd, DataExtAdd, InvoiceAdd
         //
         $dependencies = array(QUICKBOOKS_ADD_DATAEXT => array(QUICKBOOKS_ADD_CUSTOMER => QuickBooks_Utilities::priorityForAction(QUICKBOOKS_ADD_CUSTOMER) - 1, QUICKBOOKS_MOD_CUSTOMER => QuickBooks_Utilities::priorityForAction(QUICKBOOKS_MOD_CUSTOMER) - 1), QUICKBOOKS_MOD_DATAEXT => array(QUICKBOOKS_ADD_CUSTOMER => QuickBooks_Utilities::priorityForAction(QUICKBOOKS_ADD_CUSTOMER) - 1, QUICKBOOKS_MOD_CUSTOMER => QuickBooks_Utilities::priorityForAction(QUICKBOOKS_MOD_CUSTOMER) - 1), QUICKBOOKS_VOID_TRANSACTION => array(QUICKBOOKS_MOD_PURCHASEORDER => QuickBooks_Utilities::priorityForAction(QUICKBOOKS_MOD_PURCHASEORDER) + 1));
     }
     // Check for dependency priorities
     if ($dependency and isset($dependencies[$action]) and isset($dependencies[$action][$dependency])) {
         // Dependency modified priority
         return $dependencies[$action][$dependency];
     } else {
         if ($key = array_search($action, $priorities)) {
             // Regular priority
             return $key;
         }
     }
     // Default priority
     return 999;
 }
示例#5
0
 /**
  * @TODO Change this to return false by default, and only catch the specific errors we're concerned with.
  * 
  */
 public static function catchall($requestID, $user, $action, $ident, $extra, &$err, $xml, $errnum, $errmsg, $config)
 {
     $Driver = QuickBooks_Driver_Singleton::getInstance();
     $ignore = array(QUICKBOOKS_IMPORT_DELETEDTXNS => true, QUICKBOOKS_QUERY_DELETEDTXNS => true, QUICKBOOKS_IMPORT_DELETEDLISTS => true, QUICKBOOKS_QUERY_DELETEDLISTS => true, QUICKBOOKS_VOID_TRANSACTION => true, QUICKBOOKS_DELETE_TRANSACTION => true, QUICKBOOKS_DELETE_LIST => true);
     if (isset($ignore[$action])) {
         // Ignore errors for these requests
         return true;
     }
     /*
     $Parser = new QuickBooks_XML($xml);
     $errnumTemp = 0;
     $errmsgTemp = '';
     $Doc = $Parser->parse($errnumTemp, $errmsgTemp);
     $Root = $Doc->getRoot();		
     $emailStr = var_export($Root->children(), true);
     	
     $List = $Root->getChildAt('QBXML QBXMLMsgsRs '.QuickBooks_Utilities::actionToResponse($action));
     $Node = current($List->children());
     */
     $map = array();
     $others = array();
     QuickBooks_SQL_Schema::mapToSchema(trim(QuickBooks_Utilities::actionToXMLElement($action)), QUICKBOOKS_SQL_SCHEMA_MAP_TO_SQL, $map, $others);
     $object = new QuickBooks_SQL_Object($map[0], trim(QuickBooks_Utilities::actionToXMLElement($action)));
     $table = $object->table();
     $existing = null;
     if ($table and is_numeric($ident)) {
         $multipart = array(QUICKBOOKS_DRIVER_SQL_FIELD_ID => $ident);
         $existing = $Driver->get(QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . $table, $multipart);
     }
     switch ($errnum) {
         case 1:
             // These errors occur when we search for something and it doesn't exist
         // These errors occur when we search for something and it doesn't exist
         case 500:
             // 	i.e. we query for invoices modified since xyz, but there are none that have been modified since then
             // This isn't really an error, just ignore it
             if ($action == QUICKBOOKS_DERIVE_CUSTOMER) {
                 // Tried to derive, doesn't exist, add it
                 $Driver->queueEnqueue($user, QUICKBOOKS_ADD_CUSTOMER, $ident, true, QuickBooks_Utilities::priorityForAction(QUICKBOOKS_ADD_CUSTOMER));
             } else {
                 if ($action == QUICKBOOKS_DERIVE_INVOICE) {
                     // Tried to derive, doesn't exist, add it
                     $Driver->queueEnqueue($user, QUICKBOOKS_ADD_INVOICE, $ident, true, QuickBooks_Utilities::priorityForAction(QUICKBOOKS_ADD_INVOICE));
                 } else {
                     if ($action == QUICKBOOKS_DERIVE_RECEIVEPAYMENT) {
                         // Tried to derive, doesn't exist, add it
                         $Driver->queueEnqueue($user, QUICKBOOKS_ADD_RECEIVEPAYMENT, $ident, true, QuickBooks_Utilities::priorityForAction(QUICKBOOKS_ADD_RECEIVEPAYMENT));
                     }
                 }
             }
             return true;
         case 1000:
             // An internal error occured
             // @todo Hopefully at some point we'll have a better idea of how to handle this error...
             return true;
             //case 3120:			// 3120 errors are handled in the 3210 error handler section
             //	break;
         //case 3120:			// 3120 errors are handled in the 3210 error handler section
         //	break;
         case 3170:
             // This list has been modified by another user.
         // This list has been modified by another user.
         case 3175:
         case 3176:
         case 3180:
             // This error can occur in several different situations, so we test per situation
             if (false !== strpos($errmsg, 'list has been modified by another user') or false !== strpos($errmsg, 'internals could not be locked') or false !== strpos($errmsg, 'failed to acquire the lock') or false !== strpos($errmsg, 'list element is in use')) {
                 // This is *not* an error, we can just send the request again, and it'll go through just fine
                 return true;
             }
             break;
         case 3200:
             // Ignore EditSequence errors (the record will be picked up and a conflict reported next time it runs... maybe?)
             if ($action == QUICKBOOKS_MOD_CUSTOMER and $existing) {
                 // Queue up a derive customer request
                 // Tried to derive, doesn't exist, add it
                 $Driver->queueEnqueue($user, QUICKBOOKS_DERIVE_CUSTOMER, $ident, true, 9999, array('ListID' => $existing['ListID']));
             } else {
                 if ($action == QUICKBOOKS_MOD_INVOICE and $existing) {
                     // Queue up a derive customer request
                     // Tried to derive, doesn't exist, add it
                     $Driver->queueEnqueue($user, QUICKBOOKS_DERIVE_INVOICE, $ident, true, 9999, array('TxnID' => $existing['TxnID']));
                 }
             }
             return true;
         case 3120:
         case 3210:
             //print_r($existing);
             //print('TXNID: [' . $existing['TxnID'] . ']');
             // 3210: The "AppliedToTxnAdd payment amount" field has an invalid value "129.43".  QuickBooks error message: You cannot pay more than the amount due.
             if ($action == QUICKBOOKS_ADD_RECEIVEPAYMENT and (false !== strpos($errmsg, 'pay more than the amount due') or false !== strpos($errmsg, 'cannot be found')) and $existing) {
                 // If this happens, we're going to try to re-submit the payment, *without* the AppliedToTxn element
                 $db_errnum = null;
                 $db_errmsg = null;
                 $Driver->query("\n\t\t\t\t\t\tUPDATE \n\t\t\t\t\t\t\t" . QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . "receivepayment_appliedtotxn \n\t\t\t\t\t\tSET \n\t\t\t\t\t\t\tqbsql_to_skip = 1 \n\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\tReceivePayment_TxnID = '%s' ", $db_errnum, $db_errmsg, null, null, array($existing['TxnID']));
                 return true;
             }
             break;
         case 3250:
             // This feature is not enabled or not available in this version of QuickBooks.
             // Do nothing (this can be safely ignored)
             return true;
         case 3260:
             // Insufficient permission level to perform this action.
         // Insufficient permission level to perform this action.
         case 3261:
             // The integrated application has no permission to ac...
             // There's nothing we can do about this, if they don't grant the user permission, just skip it
             return true;
         case 3100:
             // Name of List Element is already in use.
             break;
         case '0x8004040D':
             // The ticket parameter is invalid  (how does this happen!?!)
             return true;
     }
     // This is our catch-all which marks the item as errored out
     if (strstr($xml, 'statusSeverity="Info"') === false) {
         $multipart = array(QUICKBOOKS_DRIVER_SQL_FIELD_ID => $ident);
         $object->set(QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_NUMBER, $errnum);
         $object->set(QUICKBOOKS_DRIVER_SQL_FIELD_ERROR_MESSAGE, $errmsg);
         // Do not set the resync field, we want resync and modified timestamps to be different
         $update_resync_field = false;
         $update_discov_field = false;
         $update_derive_field = false;
         if ($table and is_numeric($ident)) {
             // Set the error message
             $Driver->update(QUICKBOOKS_DRIVER_SQL_PREFIX_SQL . $table, $object, array($multipart), $update_resync_field, $update_discov_field, $update_derive_field);
         }
     }
     // Please don't change this, it stops us from knowing what's actually
     //	going wrong. If an error occurs, we should either catch it if it's
     //	recoverable, or treated as a fatal error so we know about it and
     //	can address it later.
     //return false;
     // I'm changing it because otherwise the sync never completes if a
     //	single error occurs... we need a way to skip errored-out records
     return true;
 }