diff --git a/commerce_xero.admin.inc b/commerce_xero.admin.inc index 7186fe2..f942a98 100644 --- a/commerce_xero.admin.inc +++ b/commerce_xero.admin.inc @@ -19,7 +19,7 @@ function commerce_xero_account_form($form, &$form_state, $bank = NULL) { $bank_options = commerce_xero_bank_account_options(); $rev_options = commerce_xero_revenue_account_options(); $method_options = commerce_payment_method_options_list(); - $tracking_categories = commerce_xero_tracking_categories_options_list(); + $form_state['tracking_categories'] = commerce_xero_tracking_categories_options_list(); if (empty($bank_options)) { drupal_set_message(t('Could not find any valid bank accounts associated with your Xero company. A bank account must have an account code in order to be used with bank transactions.'), 'error'); @@ -70,12 +70,13 @@ function commerce_xero_account_form($form, &$form_state, $bank = NULL) { '#default_value' => isset($bank) ? $bank->transaction_type : '', ); - $form['tracking_category'] = array( + $form['tracking_option'] = array( '#type' => 'select', '#title' => t('Xero tracking category'), '#description' => t('Choose the tracking category the transaction should be listed under.'), - '#options' => $tracking_categories, - '#default_value' => isset($bank) ? $bank->tracking_category : '', + '#options' => $form_state['tracking_categories'], + '#element_validate' => array('commerce_xero_account_tracking_option_validate'), + '#default_value' => isset($bank) ? _commerce_xero_account_extract_tracking_value($form_state['tracking_categories'], $bank->tracking_option) : '', ); $form['actions'] = array('#type' => 'actions'); @@ -100,6 +101,49 @@ function commerce_xero_account_form($form, &$form_state, $bank = NULL) { } /** + * Helper function to extract tracking category option key from tracking + * categories array based on the the label. + * + * @param $categories + * Tracking categories. + * @param $option + * The tracking option. + * @return integer + * The key in the array. + */ +function _commerce_xero_account_extract_tracking_value($categories, $option) { + return array_reduce($categories, function(&$result, $item) use ($option) { + if (!empty($result) || !is_array($item)) { + return $result; + } + + $values = array_flip($item); + if (isset($values[$option])) { + $result = $values[$option]; + } + + return $result; + }, ''); +} + +/** + * Commerce Xero Account Tracking Category/Option Validate + */ +function commerce_xero_account_tracking_option_validate($element, &$form_state) { + // Set the value for the tracking category by its respective tracking option. + if (!empty($form_state['values']['tracking_option']) && $form_state['values']['tracking_option'] <> '_none') { + $opt_value = $form_state['values']['tracking_option']; + foreach ($form_state['tracking_categories'] as $category => $options) { + if (is_array($options) && isset($options[$opt_value])) { + form_set_value(array('#parents' => array('tracking_category')), $category, $form_state); + form_set_value($element, $options[$opt_value], $form_state); + break; + } + } + } +} + +/** * Commerce Xero Account Form Validate */ function commerce_xero_account_form_validate($form, &$form_state) { @@ -115,7 +159,7 @@ function commerce_xero_account_form_validate($form, &$form_state) { } /** - * Commerce Xero Account Form Delete + * Commerce Xero Account Form Delete */ function commerce_xero_account_form_delete($form, &$form_state) { $form_state['redirect'] = 'admin/commerce/config/xero/account/' . $form_state['account']->id . '/delete'; @@ -136,6 +180,7 @@ function commerce_xero_account_form_submit($form, &$form_state) { 'bank_account' => '', 'transaction_type' => '', 'tracking_category' => '', + 'tracking_option' => '', ); } @@ -144,6 +189,7 @@ function commerce_xero_account_form_submit($form, &$form_state) { $bank->bank_account = $form_state['values']['bank_account']; $bank->transaction_type = $form_state['values']['transaction_type']; $bank->tracking_category = $form_state['values']['tracking_category']; + $bank->tracking_option = $form_state['values']['tracking_option']; if (isset($bank->id)) { $ret = drupal_write_record('commerce_xero_bankaccount', $bank, array('id')); @@ -161,15 +207,15 @@ function commerce_xero_account_form_submit($form, &$form_state) { 'type' => 'xero_textfield', 'settings' => array( 'xero_type' => array('BankTransaction', 'Payment'), - ), - ), + ), + ), 'display' => array( 'default' => array( 'type' => 'xero_reference', 'label' => 'inline', 'settings' => array( 'display' => array('type', 'guid'), - ), + ), ), ), ); diff --git a/commerce_xero.install b/commerce_xero.install index c697568..6dd7e66 100644 --- a/commerce_xero.install +++ b/commerce_xero.install @@ -19,6 +19,7 @@ function commerce_xero_schema() { 'payment_method' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE), 'transaction_type' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE), 'tracking_category' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE, 'default' => ''), + 'tracking_option' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE, 'default' => ''), ), 'primary key' => array('id'), 'unique key' => array( @@ -116,3 +117,11 @@ function commerce_xero_update_7002() { $schema = drupal_get_schema_unprocessed('commerce_xero', 'commerce_xero_bankaccount'); db_add_field('commerce_xero_bankaccount', 'tracking_category', $schema['fields']['tracking_category']); } + +/** + * Add the tracking option field to the bank accounts table. + */ +function commerce_xero_update_7003() { + $schema = drupal_get_schema_unprocessed('commerce_xero', 'commerce_xero_bankaccount'); + db_add_field('commerce_xero_bankaccount', 'tracking_option', $schema['fields']['tracking_option']); +} diff --git a/commerce_xero.module b/commerce_xero.module index 65d4226..510c09d 100644 --- a/commerce_xero.module +++ b/commerce_xero.module @@ -149,6 +149,37 @@ function commerce_xero_views_api() { } /** + * Implements hook_xero_make_info(). + */ +function commerce_xero_xero_make_info() { + return array( + 'tracking' => array( + 'file path' => drupal_get_path('module', 'commerce_xero') . '/commerce_xero.make.inc' + ), + ); +} + +/** + * Helper function to extract the correct array if 1 or greater elements in a + * Xero result set. + * + * @param $arr + * The array of one or more items for a xero type i.e. pass in + * $result['TrackingCategories']. + * @param $type + * The xero type, singular, to check in the array. + * @return array + * An array of one or more items. + */ +function _commerce_xero_extract_items($arr, $type) { + if (isset($arr[$type][0])) { + return $arr[$type]; + } + + return $arr; +} + +/** * Load xero bank account. * * @param $id @@ -243,20 +274,24 @@ function commerce_xero_revenue_account_options() { */ function commerce_xero_tracking_categories_options_list() { $xero_tracking_categories = &drupal_static(__FUNCTION__, array()); + $ret = array('_none' => t('- None -')); if (!$xero_tracking_categories) { $xero_tracking_categories = xero_query('get', 'TrackingCategories', FALSE, FALSE); + $xero_tracking_categories = _commerce_xero_extract_items($xero_tracking_categories['TrackingCategories'], 'TrackingCategory'); } - $options = array('' => t('-- None --')); - $options += array_reduce($xero_tracking_categories['TrackingCategories'], function(&$result, $item) { - foreach ($item['Options']['Option'] as $option) { - $result[$item['Name']][$option['Name']] = $option['Name']; + $n = 0; + + foreach ($xero_tracking_categories as $category => $options) { + $category_name = $options['Name']; + foreach ($options['Options']['Option'] as $option) { + $ret[$category_name][$n] = $option['Name']; + $n++; } - return $result; - }); + } - return $options; + return $ret; } /** @@ -548,6 +583,16 @@ function commerce_xero_create_banktransaction($payment, $order, $bank) { $transaction['BankTransaction']['LineItems'][0]['LineItem']['AccountCode'] = $bank->revenue_code; $transaction['BankTransaction']['LineItems'][0]['LineItem']['LineAmount'] = $total_amount; + // Add tracking category. + if ($bank->tracking_category) { + $tracking_options = array( + 'options' => array( + $bank->tracking_category => $bank->tracking_option, + ), + ); + $transaction['BankTransaction']['LineItems'][0]['LineItem']['Tracking'] = xero_make('tracking', 'all', $tracking_options); + } + // It is safe to only have the total amount because the line items are inclusive. $transaction['BankTransaction']['Total'] = $total_amount; @@ -608,3 +653,4 @@ function commerce_xero_create_invoice_payment($payment, $order, $bank, $invoice) return FALSE; } +