From a58790289b9dbfad388a1976f07cee5336ca8d95 Mon Sep 17 00:00:00 2001
From: Christian Spitzlay <christian.spitzlay@bio.logis.de>
Date: Mon, 10 Sep 2012 18:24:24 +0200
Subject: [PATCH] implement new callback-based method for invoice number
 generation see also: http://drupal.org/node/1728106

---
 commerce_invoice.module                   |  4 ++++
 commerce_invoice_ui.info                  |  1 +
 includes/commerce_invoice.controller.inc  | 16 +++++++++++++--
 includes/commerce_invoice_ui.invoices.inc | 34 +++++++++++++++++++++++++++++--
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/commerce_invoice.module b/commerce_invoice.module
index dbd631a..4e3f773 100644
--- a/commerce_invoice.module
+++ b/commerce_invoice.module
@@ -17,6 +17,10 @@ define('COMMERCE_INVOICE_METHOD_YEAR', 'Y-[invoice_id]');
 // Invoice id is regenerated every month
 define('COMMERCE_INVOICE_METHOD_MONTH', 'Y-m-[invoice_id]');
 
+// Invoice number is generated by a callback that is being passed the invoice object
+define('COMMERCE_INVOICE_METHOD_CALLBACK', 'callback');
+
+
 /**
  * Implements hook_entity_info().
  */
diff --git a/commerce_invoice_ui.info b/commerce_invoice_ui.info
index fe5fc3d..26dfaa7 100644
--- a/commerce_invoice_ui.info
+++ b/commerce_invoice_ui.info
@@ -8,4 +8,5 @@ dependencies[] = field_ui
 dependencies[] = commerce
 dependencies[] = commerce_ui
 dependencies[] = commerce_invoice
+dependencies[] = ctools
 dependencies[] = views
diff --git a/includes/commerce_invoice.controller.inc b/includes/commerce_invoice.controller.inc
index 443b519..3f48d52 100644
--- a/includes/commerce_invoice.controller.inc
+++ b/includes/commerce_invoice.controller.inc
@@ -53,7 +53,7 @@ class CommerceInvoiceEntityController extends DrupalCommerceEntityController {
       // Inserting new invoice
       if (empty($invoice->invoice_id)) {
         $invoice->created = REQUEST_TIME;
-        $invoice->invoice_number = $this->generate_invoice_id();
+        $invoice->invoice_number = $this->generate_invoice_id($invoice);
 
         $this->invoke('presave', $invoice);
         $invoice = $this->_save($invoice, $transaction);
@@ -112,10 +112,12 @@ class CommerceInvoiceEntityController extends DrupalCommerceEntityController {
   /**
    * Generates invoice id
    *
+   * @param object $invoice The invoice to generate an invoice number for.
+   *
    * @return
    *   The generated invoice id
    */
-  protected function generate_invoice_id() {
+  protected function generate_invoice_id($invoice) {
     // TODO: there is probably a better way to do this
     // Invoice generation method
     $method = variable_get('commerce_invoice_number_method', COMMERCE_INVOICE_METHOD_YEAR);
@@ -170,6 +172,16 @@ class CommerceInvoiceEntityController extends DrupalCommerceEntityController {
           }
           $return = date('Y') . '-' . date('m') . '-' . $id;
           break;
+        case COMMERCE_INVOICE_METHOD_CALLBACK:
+          $function_name = variable_get('commerce_invoice_number_callback', '');
+          if (empty($function_name) || !function_exists($function_name)) {
+            drupal_set_message(t('No valid callback defined for invoice number generation.'), 'error');
+            $return = t('no-invoice-number');
+          }
+          else {
+            $return = $function_name($invoice);
+          }
+          break;
       }
       return $return;
 
diff --git a/includes/commerce_invoice_ui.invoices.inc b/includes/commerce_invoice_ui.invoices.inc
index a72861e..9a1653e 100644
--- a/includes/commerce_invoice_ui.invoices.inc
+++ b/includes/commerce_invoice_ui.invoices.inc
@@ -18,9 +18,39 @@ function commerce_invoice_settings_form($form, &$form_state) {
     '#options' => array(
       COMMERCE_INVOICE_METHOD_INFINITE => t('Infinite (one single number, that is never reset, and incremented at each invoice generation)'),
       COMMERCE_INVOICE_METHOD_YEAR => t('Reset every year, with an id incremented at each invoice generation (@invoice_number)', array('@invoice_number' => date('Y').'-[invoice_id]')),
-      COMMERCE_INVOICE_METHOD_MONTH => t('Reset every month, with an id incremented at each invoice generation (@invoice_number)', array('@invoice_number' => date('Y-m').'-[invoice_id]'))
-    )
+      COMMERCE_INVOICE_METHOD_MONTH => t('Reset every month, with an id incremented at each invoice generation (@invoice_number)', array('@invoice_number' => date('Y-m').'-[invoice_id]')),
+      COMMERCE_INVOICE_METHOD_CALLBACK => t('Invoice number generation is controlled by a callback function that is being passed the invoice object')
+    ),
+  );
+
+  $callbacks = module_invoke_all('commerce_invoice_number_callbacks');
+  $options = array_combine($callbacks, $callbacks);
+
+  $form['commerce_invoice_number_callback'] = array(
+    '#type' => 'select',
+    '#title' => t('Invoice number creation callback'),
+    '#description' => t('This selects the callback function for the callback method.'),
+    '#default_value' => variable_get('commerce_invoice_number_callback', ''),
+    '#options' => $options,
+    '#element_validate' => array('commerce_invoice_ui_validate_invoice_number_callback'),
+    '#states' => array(
+      'visible' => array(
+        ':input[name="commerce_invoice_number_method"]' => array('value' => COMMERCE_INVOICE_METHOD_CALLBACK),
+      ),
+    ),
   );
 
   return system_settings_form($form);
 }
+
+function commerce_invoice_ui_validate_invoice_number_callback($element, &$form_state, $form) {
+  if ($form_state['values']['commerce_invoice_number_method'] == COMMERCE_INVOICE_METHOD_CALLBACK) {
+    if (empty($form_state['values']['commerce_invoice_number_callback'])) {
+      form_set_error('commerce_invoice_number_callback', t('Please specify a callback function.'));
+    }
+    elseif (!function_exists($form_state['values']['commerce_invoice_number_callback'])) {
+      form_set_error('commerce_invoice_number_callback', t('"@callback" is not a valid callback function.', array('@callback' => $form_state['values']['commerce_invoice_number_callback'])));
+    }
+  }
+}
+
-- 
1.7.12

