/** * Pull contacts from Xero and store them into civicrm_account_contact. * * We call the civicrm_accountPullPreSave hook so other modules can alter if required * * @param array $params * * @return bool * @throws API_Exception * @throws CRM_Core_Exception */ public function pull($params) { try { $result = $this->getSingleton($params['connector_id'])->Invoices(FALSE, $this->formatDateForXero($params['start_date']), array("Type" => "ACCREC")); if (!is_array($result)) { throw new API_Exception('Sync Failed', 'xero_retrieve_failure', (array) $result); } $errors = array(); if (!empty($result['Invoices'])) { $invoices = $result['Invoices']['Invoice']; if (isset($invoices['InvoiceID'])) { // the return syntax puts the contact only level higher up when only one contact is involved $invoices = array($invoices); } foreach ($invoices as $invoice) { $save = TRUE; $params = array('contribution_id' => CRM_Utils_Array::value('InvoiceNumber', $invoice), 'accounts_modified_date' => $invoice['UpdatedDateUTC'], 'plugin' => 'xero', 'accounts_invoice_id' => $invoice['InvoiceID'], 'accounts_data' => json_encode($invoice), 'accounts_status_id' => $this->mapStatus($invoice['Status']), 'accounts_needs_update' => 0, 'connector_id' => $params['connector_id']); CRM_Accountsync_Hook::accountPullPreSave('invoice', $invoice, $save, $params); if (!$save) { continue; } try { $params['id'] = civicrm_api3('AccountInvoice', 'getvalue', array('return' => 'id', 'accounts_invoice_id' => $invoice['InvoiceID'], 'plugin' => $this->_plugin)); } catch (CiviCRM_API3_Exception $e) { // this is an update - but lets just check the contact id doesn't exist in the account_contact table first // e.g if a list has been generated but not yet pushed try { $existing = civicrm_api3('AccountInvoice', 'getsingle', array('return' => 'id', 'contribution_id' => $invoice['InvoiceNumber'], 'plugin' => $this->_plugin)); $params['id'] = $existing['id']; if (!empty($existing['accounts_invoice_id']) && $existing['accounts_invoice_id'] != $invoice['InvoiceID']) { // no idea how this happened or what it means - calling function can catch & deal with it throw new CRM_Core_Exception(ts('Cannot update invoice'), 'data_error', $invoice); } } catch (CiviCRM_API3_Exception $e) { // ok - it IS an update } } try { civicrm_api3('AccountInvoice', 'create', $params); } catch (CiviCRM_API3_Exception $e) { $errors[] = ts('Failed to store ') . $invoice['InvoiceNumber'] . ' (' . $invoice['InvoiceID'] . ' )' . ts(' with error ') . $e->getMessage() . ts('Invoice Pull failed'); } } } if ($errors) { // Since we expect this to wind up in the job log we'll print the errors throw new CRM_Core_Exception(ts('Not all records were saved') . print_r($errors, TRUE), 'incomplete', $errors); } return TRUE; } catch (CRM_Civixero_Exception_XeroThrottle $e) { throw new CRM_Core_Exception('Invoice Pull aborted due to throttling by Xero'); } }
/** * Pull contacts from Xero and store them into civicrm_account_contact. * * We call the civicrm_accountPullPreSave hook so other modules can alter if required * * @param array $params * * @throws API_Exception * @throws CRM_Core_Exception */ public function pull($params) { try { $result = $this->getSingleton($params['connector_id'])->Contacts(FALSE, $this->formatDateForXero($params['start_date'])); if (!is_array($result)) { throw new API_Exception('Sync Failed', 'xero_retrieve_failure', (array) $result); } if (!empty($result['Contacts'])) { $contacts = $result['Contacts']['Contact']; if (isset($contacts['ContactID'])) { // the return syntax puts the contact only level higher up when only one contact is involved $contacts = array($contacts); } foreach ($contacts as $contact) { $save = TRUE; $params = array('accounts_display_name' => $contact['Name'], 'contact_id' => CRM_Utils_Array::value('ContactNumber', $contact), 'accounts_modified_date' => $contact['UpdatedDateUTC'], 'plugin' => 'xero', 'accounts_contact_id' => $contact['ContactID'], 'accounts_data' => json_encode($contact)); CRM_Accountsync_Hook::accountPullPreSave('contact', $contact, $save, $params); if (!$save) { continue; } try { $params['id'] = civicrm_api3('account_contact', 'getvalue', array('return' => 'id', 'accounts_contact_id' => $contact['ContactID'], 'plugin' => $this->_plugin)); } catch (CiviCRM_API3_Exception $e) { // this is an update - but lets just check the contact id doesn't exist in the account_contact table first // e.g if a list has been generated but not yet pushed try { $existing = civicrm_api3('account_contact', 'getsingle', array('return' => 'id', 'contact_id' => $contact['ContactNumber'], 'plugin' => $this->_plugin)); if (!empty($existing['accounts_contact_id']) && $existing['accounts_contact_id'] != $contact['ContactID']) { // no idea how this happened or what it means - calling function can catch & deal with it throw new CRM_Core_Exception(ts('Cannot update contact'), 'data_error', $contact); } } catch (CiviCRM_API3_Exception $e) { // ok - it IS an update } } try { civicrm_api3('account_contact', 'create', $params); } catch (CiviCRM_API3_Exception $e) { CRM_Core_Session::setStatus(ts('Failed to store ') . $params['accounts_display_name'] . ts(' with error ') . $e->getMessage(), ts('Contact Pull failed')); } } } } catch (CRM_Civixero_Exception_XeroThrottle $e) { throw new CRM_Core_Exception('Invoice Pull aborted due to throttling by Xero'); } }