Index: invoice.install
===================================================================
--- invoice.install	(revision 1)
+++ invoice.install	(working copy)
@@ -1,344 +1,390 @@
-<?php
-// $Id: invoice.install,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
-
-/**
- * @file
- * Invoice module
- * 
- * This module was developed by Platina Designs, http://www.platinadesigns.nl
- *
- * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
- * @date Change 11 nov 2008: Added and tested invoice_update_1() function, works 100% correct.
- */
-require_once dirname(__FILE__) .'/invoice_helpers.inc';
-
-/**
- * Implementation of hook_install()
- */
-function invoice_install() {
-
-  drupal_install_schema('invoice');  
-  variable_set('invoice_locale', 'en_US.utf8');
-  variable_set('invoice_date_format', 'm/d/Y');
-  variable_set('invoice_pay_limit', '14'); // Pay limit in days
-  variable_set('invoice_vat', '19'); // VAT percentage
-  variable_set('invoice_invoice_number_zerofill', 4);
-  variable_set('invoice_invoice_number_prefix', '%Y');
-  variable_set('invoice_default_template', 'default');
-  variable_set('invoice_supplier_company_name', 'My company');
-
-  variable_set('invoice_display_column_vat', 0); // By default the VAT column is not displayed, however if there is more than 1 different VAT the VAT column will still be shown. (is required by law)
-  variable_set('invoice_display_column_exunitcost', 1);
-  variable_set('invoice_display_column_incunitcost', 1);
-  variable_set('invoice_display_column_extotal', 1);
-  variable_set('invoice_display_column_inctotal', 1);
-  
-  _make_sure_node_promote_flag_is_off();
-}
-
-/**
- * Implementation of hook_uninstall()
- */
-function invoice_uninstall() {
-  // Drop all invoice tables
-  // drupal_uninstall_schema('invoice'); // If some admin get hacked, it's probably not desirable that all invoices can be deleted in a few steps
-}
-
-/**
- * Implementation of hook_update_N()
- * 
- * @return array Array with query results
- */
-function invoice_update_1() {
-  $ret = array(); // Array to which query results will be added.
-    
-  // Update invoice_customers table
-  db_add_index($ret, 'invoice_customers', 'cid', array('cid'));
-  db_drop_primary_key($ret, 'invoice_customers');
-  db_change_field($ret, 'invoice_customers', 'cid', 'cid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('cid')));
-  db_drop_index($ret, 'invoice_customers', 'cid');    
-
-  db_change_field($ret, 'invoice_customers', 'customer_number', 'customer_number', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_change_field($ret, 'invoice_customers', 'company_name', 'company_name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'firstname', 'firstname', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'lastname', 'lastname', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'street', 'street', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'building_number', 'building_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'zipcode', 'zipcode', array('type' => 'varchar', 'length' => 10, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'city', 'city', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'country', 'country', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'coc_number', 'coc_number', array('type' => 'varchar', 'length' => 25, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'vat_number', 'vat_number', array('type' => 'varchar', 'length' => 25, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_customers', 'description', 'description', array('type' => 'text', 'not null' => FALSE));
-  
-  db_drop_index($ret, 'invoice_customers', 'invoice_id');
-  db_change_field($ret, 'invoice_customers', 'invoice_id', 'invoice_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_index($ret, 'invoice_customers', 'invoice_id', array('invoice_id'));
-  
-  db_add_index($ret, 'invoice_customers', 'customer_number', array('customer_number'));
-  
-  // Update invoice_invoices table
-  db_add_index($ret, 'invoice_invoices', 'iid', array('iid'));
-  db_drop_primary_key($ret, 'invoice_invoices');
-  db_change_field($ret, 'invoice_invoices', 'iid', 'iid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('iid')));
-  db_drop_index($ret, 'invoice_invoices', 'iid');
-    
-  db_change_field($ret, 'invoice_invoices', 'description', 'description', array('type' => 'text', 'not null' => FALSE));
-  
-  db_change_field($ret, 'invoice_invoices', 'tid', 'tid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_index($ret, 'invoice_invoices', 'tid', array('tid'));
-    
-  db_change_field($ret, 'invoice_invoices', 'pay_limit', 'pay_limit', array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));  
-  db_change_field($ret, 'invoice_invoices', 'pay_status', 'pay_status', array('type' => 'varchar', 'length' => 10, 'not null' => TRUE, 'default' => 'unpaid'));
-  db_drop_field($ret, 'invoice_invoices', 'depricated_created');
-  
-  db_drop_index($ret, 'invoice_invoices', 'nid');
-  db_change_field($ret, 'invoice_invoices', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_unique_key($ret, 'invoice_invoices', 'nid', array('nid'));
-  
-  db_drop_index($ret, 'invoice_invoices', 'uid');
-  db_change_field($ret, 'invoice_invoices', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE));
-  db_add_index($ret, 'invoice_invoices', 'uid', array('uid'));
-  
-  // Update invoice_items table
-  db_add_index($ret, 'invoice_items', 'iid', array('iid'));
-  db_drop_primary_key($ret, 'invoice_items');
-  db_change_field($ret, 'invoice_items', 'iid', 'iid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('iid')));
-  db_drop_index($ret, 'invoice_items', 'iid');
-  
-  db_change_field($ret, 'invoice_items', 'description', 'description', array('type' => 'text', 'size' => 'medium', 'not null' => FALSE));
-  db_change_field($ret, 'invoice_items', 'unitcost', 'unitcost', array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0));
-    
-  db_change_field($ret, 'invoice_items', 'vat', 'vat', array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_change_field($ret, 'invoice_items', 'weight', 'weight', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-    
-  db_drop_index($ret, 'invoice_items', 'uid');
-  db_change_field($ret, 'invoice_items', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE));
-  db_add_index($ret, 'invoice_items', 'uid', array('uid'));
-  
-  db_change_field($ret, 'invoice_items', 'created', 'created', array('type' => 'datetime', 'not null' => TRUE));
-  
-  db_drop_index($ret, 'invoice_items', 'invoice_id');
-  db_change_field($ret, 'invoice_items', 'invoice_id', 'invoice_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_index($ret, 'invoice_items', 'invoice_id', array('invoice_id'));
-  
-  // Update invoice_templates table
-  db_add_index($ret, 'invoice_templates', 'tid', array('tid'));
-  db_drop_primary_key($ret, 'invoice_templates');
-  db_change_field($ret, 'invoice_templates', 'tid', 'tid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('tid')));
-  db_drop_index($ret, 'invoice_templates', 'tid');
-  
-  db_drop_unique_key($ret, 'invoice_templates', 'name');
-  db_change_field($ret, 'invoice_templates', 'name', 'name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_add_unique_key($ret, 'invoice_templates', 'name', array('name'));
-  
-  db_change_field($ret, 'invoice_templates', 'locale', 'locale', array('type' => 'varchar', 'length' => '25', 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'date_format', 'date_format', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'vat', 'vat', array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_change_field($ret, 'invoice_templates', 'pay_limit', 'pay_limit', array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_change_field($ret, 'invoice_templates', 'supplier_company_name', 'supplier_company_name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_street', 'supplier_street', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_building_number', 'supplier_building_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_zipcode', 'supplier_zipcode', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_city', 'supplier_city', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_country', 'supplier_country', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_phone', 'supplier_phone', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_fax', 'supplier_fax', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_email', 'supplier_email', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_web', 'supplier_web', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_coc_number', 'supplier_coc_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  db_change_field($ret, 'invoice_templates', 'supplier_vat_number', 'supplier_vat_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
-  
-  return $ret; // Array with query results.
-}
-
-/**
- * Implementation of hook_update_N()
- * 
- * @return array Array with query results
- */
-function invoice_update_2() {
-  $ret = array(); // Array to which query results will be added.
-  
-  db_add_field($ret, 'invoice_templates', 'display_column_vat', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_field($ret, 'invoice_templates', 'display_column_exunitcost', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
-  db_add_field($ret, 'invoice_templates', 'display_column_incunitcost', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
-  db_add_field($ret, 'invoice_templates', 'display_column_extotal', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
-  db_add_field($ret, 'invoice_templates', 'display_column_inctotal', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
-  
-  return $ret; // Array with query results.
-}
-
-/**
- * Implementation of hook_update_N()
- * 
- * @return array Array with query results
- */
-function invoice_update_3() {
-  $ret = array(); // Array to which query results will be added.
-  
-  if (is_null(variable_get('invoice_invoice_number_zerofill', NULL))) {
-    variable_set('invoice_invoice_number_zerofill', 4);
-  }
-  
-  if (is_null(variable_get('invoice_invoice_number_prefix', NULL))) {
-    variable_set('invoice_invoice_number_prefix', '%Y');
-  }
-  
-  db_add_field($ret, 'invoice_invoices', 'leading_zeros', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-  db_add_field($ret, 'invoice_invoices', 'prefix', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
-  
-  return $ret; // Array with query results.
-}
-
-/**
- * Implementation of hook_update_N()
- * 
- * This update fixes a privacy issue
- * 
- * @return array Array with query results
- */
-function invoice_update_4() {
-
-  _make_sure_node_promote_flag_is_off();
-
-  // Make already created invoice nodes secure
-  db_query("UPDATE {node} SET promote=0 WHERE type='invoice'");
-  
-  return array();
-}
-
-/**
- * Implementation of hook_update_N()
- * 
- * @return array Array with query results
- */
-function invoice_update_5() {
-  // If these settings are not set already, set the default values. 
-  
-  $var1 = variable_get('invoice_display_column_vat', NULL);
-  $var2 = variable_get('invoice_display_column_exunitcost', NULL);
-  $var3 = variable_get('invoice_display_column_incunitcost', NULL);
-  $var4 = variable_get('invoice_display_column_extotal', NULL);
-  $var5 = variable_get('invoice_display_column_inctotal', NULL);
-  
-  if (is_null($var1) && is_null($var2) && is_null($var3) && is_null($var4) && is_null($var5)) {
-    variable_set('invoice_display_column_vat', 0);
-    variable_set('invoice_display_column_exunitcost', 1);
-    variable_set('invoice_display_column_incunitcost', 1);
-    variable_set('invoice_display_column_extotal', 1);
-    variable_set('invoice_display_column_inctotal', 1);    
-  }  
-  
-  return array();
-}
-
-/**
- * Implementation of hook_schema()
- *
- * @return array
- */
-function invoice_schema() {
-  
-  $schema['invoice_customers'] = array(
-    'fields' => array(
-      'cid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
-      'customer_number'  => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'company_name'     => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'firstname'        => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'lastname'         => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'street'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'building_number'  => array('type' => 'varchar', 'length' => 15, 'not null' => FALSE),
-      'zipcode'          => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
-      'city'             => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'country'          => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'coc_number'       => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
-      'vat_number'       => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
-      'description'      => array('type' => 'text', 'not null' => FALSE),
-      'invoice_id'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-    ),
-    'primary key'        => array('cid'),
-    'unique keys'        => array(),
-    'indexes' => array(
-      'invoice_id'       => array('invoice_id'),
-      'customer_number'  => array('customer_number'),
-    ),
-  );
-  
-  $schema['invoice_invoices'] = array(
-    'fields' => array(
-      'iid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
-      'nid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'leading_zeros'    => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'prefix'           =>  array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'description'      => array('type' => 'text', 'not null' => FALSE),
-      'tid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'pay_limit'        => array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'pay_status'       => array('type' => 'varchar', 'length' => 10, 'not null' => TRUE, 'default' => 'unpaid'),
-      'uid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE),
-    ),
-    'primary key'        => array('iid'),
-    'unique keys' => array(
-      'nid'             => array('nid'),
-    ),
-    'indexes' => array(
-      'tid'              => array('tid'),
-      'uid'              => array('uid'),
-    ),
-  );
-  
-  $schema['invoice_items'] = array(
-   'fields' => array(
-      'iid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
-      'description'      => array('type' => 'text', 'size' => 'medium', 'not null' => FALSE),
-      'quantity'         => array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0),
-      'unitcost'         => array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0),
-      'vat'              => array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'weight'           => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'invoice_id'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'uid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE),
-      'created'          => array('type' => 'datetime', 'not null' => TRUE),
-    ),
-    'primary key'        => array('iid'),
-    'unique keys'        => array(),
-    'indexes' => array(
-      'invoice_id'       => array('invoice_id'),
-      'uid'              => array('uid'),
-    ),
-  );
-
-  $schema['invoice_templates'] = array(
-    'fields' => array(
-      'tid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
-      'name'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'locale'           => array('type' => 'varchar', 'length' => '25', 'not null' => FALSE),
-      'date_format'      => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
-      'vat'              => array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'pay_limit'        => array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'supplier_company_name'      => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_street'            => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_building_number'   => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_zipcode'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_city'              => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_country'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_phone'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_fax'               => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_email'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_web'               => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_coc_number'        => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'supplier_vat_number'        => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
-      'display_column_vat'         => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
-      'display_column_exunitcost'  => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
-      'display_column_incunitcost' => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
-      'display_column_extotal'     => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
-      'display_column_inctotal'    => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
-    ),
-    'primary key'        => array('tid'),
-    'unique keys' => array(
-      'name'             => array('name'),
-    ),
-    'indexes'            => array(),
-  );
-  
-  return $schema;
-}
+<?php
+// $Id: invoice.install,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
+
+/**
+ * @file
+ * Invoice module
+ * 
+ * This module was developed by Platina Designs, http://www.platinadesigns.nl
+ *
+ * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
+ * @date Change 11 nov 2008: Added and tested invoice_update_1() function, works 100% correct.
+ */
+require_once dirname(__FILE__) .'/invoice_helpers.inc';
+
+/**
+ * Implementation of hook_install()
+ */
+function invoice_install() {
+
+  drupal_install_schema('invoice');  
+  variable_set('invoice_locale', 'en_US.utf8');
+  variable_set('invoice_date_format', 'm/d/Y');
+  variable_set('invoice_pay_limit', '14'); // Pay limit in days
+  variable_set('invoice_vat', '19'); // VAT percentage
+  variable_set('invoice_invoice_number_zerofill', 4);
+  variable_set('invoice_invoice_number_prefix', '%Y');
+  variable_set('invoice_default_template', 'default');
+  variable_set('invoice_supplier_company_name', 'My company');
+
+  variable_set('invoice_display_column_vat', 0); // By default the VAT column is not displayed, however if there is more than 1 different VAT the VAT column will still be shown. (is required by law)
+  variable_set('invoice_display_column_exunitcost', 1);
+  variable_set('invoice_display_column_incunitcost', 1);
+  variable_set('invoice_display_column_extotal', 1);
+  variable_set('invoice_display_column_inctotal', 1);
+  
+  _make_sure_node_promote_flag_is_off();
+}
+
+/**
+ * Implementation of hook_uninstall()
+ */
+function invoice_uninstall() {
+  // Drop all invoice tables
+  drupal_uninstall_schema('invoice'); // If some admin get hacked, it's probably not desirable that all invoices can be deleted in a few steps
+}
+
+/**
+ * Implementation of hook_update_N()
+ * 
+ * @return array Array with query results
+ */
+function invoice_update_1() {
+  $ret = array(); // Array to which query results will be added.
+    
+  // Update invoice_customers table
+  db_add_index($ret, 'invoice_customers', 'cid', array('cid'));
+  db_drop_primary_key($ret, 'invoice_customers');
+  db_change_field($ret, 'invoice_customers', 'cid', 'cid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('cid')));
+  db_drop_index($ret, 'invoice_customers', 'cid');    
+
+  db_change_field($ret, 'invoice_customers', 'customer_number', 'customer_number', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_change_field($ret, 'invoice_customers', 'company_name', 'company_name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'firstname', 'firstname', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'lastname', 'lastname', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'street', 'street', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'building_number', 'building_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'zipcode', 'zipcode', array('type' => 'varchar', 'length' => 10, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'city', 'city', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'country', 'country', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'coc_number', 'coc_number', array('type' => 'varchar', 'length' => 25, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'vat_number', 'vat_number', array('type' => 'varchar', 'length' => 25, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_customers', 'description', 'description', array('type' => 'text', 'not null' => FALSE));
+  
+  db_drop_index($ret, 'invoice_customers', 'invoice_id');
+  db_change_field($ret, 'invoice_customers', 'invoice_id', 'invoice_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_index($ret, 'invoice_customers', 'invoice_id', array('invoice_id'));
+  
+  db_add_index($ret, 'invoice_customers', 'customer_number', array('customer_number'));
+  
+  // Update invoice_invoices table
+  db_add_index($ret, 'invoice_invoices', 'iid', array('iid'));
+  db_drop_primary_key($ret, 'invoice_invoices');
+  db_change_field($ret, 'invoice_invoices', 'iid', 'iid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('iid')));
+  db_drop_index($ret, 'invoice_invoices', 'iid');
+    
+  db_change_field($ret, 'invoice_invoices', 'description', 'description', array('type' => 'text', 'not null' => FALSE));
+  
+  db_change_field($ret, 'invoice_invoices', 'tid', 'tid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_index($ret, 'invoice_invoices', 'tid', array('tid'));
+    
+  db_change_field($ret, 'invoice_invoices', 'pay_limit', 'pay_limit', array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));  
+  db_change_field($ret, 'invoice_invoices', 'pay_status', 'pay_status', array('type' => 'varchar', 'length' => 10, 'not null' => TRUE, 'default' => 'unpaid'));
+  db_drop_field($ret, 'invoice_invoices', 'depricated_created');
+  
+  db_drop_index($ret, 'invoice_invoices', 'nid');
+  db_change_field($ret, 'invoice_invoices', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_unique_key($ret, 'invoice_invoices', 'nid', array('nid'));
+  
+  db_drop_index($ret, 'invoice_invoices', 'uid');
+  db_change_field($ret, 'invoice_invoices', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE));
+  db_add_index($ret, 'invoice_invoices', 'uid', array('uid'));
+  
+  // Update invoice_items table
+  db_add_index($ret, 'invoice_items', 'iid', array('iid'));
+  db_drop_primary_key($ret, 'invoice_items');
+  db_change_field($ret, 'invoice_items', 'iid', 'iid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('iid')));
+  db_drop_index($ret, 'invoice_items', 'iid');
+  
+  db_change_field($ret, 'invoice_items', 'description', 'description', array('type' => 'text', 'size' => 'medium', 'not null' => FALSE));
+  db_change_field($ret, 'invoice_items', 'unitcost', 'unitcost', array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0));
+    
+  db_change_field($ret, 'invoice_items', 'vat', 'vat', array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_change_field($ret, 'invoice_items', 'weight', 'weight', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+    
+  db_drop_index($ret, 'invoice_items', 'uid');
+  db_change_field($ret, 'invoice_items', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE));
+  db_add_index($ret, 'invoice_items', 'uid', array('uid'));
+  
+  db_change_field($ret, 'invoice_items', 'created', 'created', array('type' => 'datetime', 'not null' => TRUE));
+  
+  db_drop_index($ret, 'invoice_items', 'invoice_id');
+  db_change_field($ret, 'invoice_items', 'invoice_id', 'invoice_id', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_index($ret, 'invoice_items', 'invoice_id', array('invoice_id'));
+  
+  // Update invoice_templates table
+  db_add_index($ret, 'invoice_templates', 'tid', array('tid'));
+  db_drop_primary_key($ret, 'invoice_templates');
+  db_change_field($ret, 'invoice_templates', 'tid', 'tid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('tid')));
+  db_drop_index($ret, 'invoice_templates', 'tid');
+  
+  db_drop_unique_key($ret, 'invoice_templates', 'name');
+  db_change_field($ret, 'invoice_templates', 'name', 'name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_add_unique_key($ret, 'invoice_templates', 'name', array('name'));
+  
+  db_change_field($ret, 'invoice_templates', 'locale', 'locale', array('type' => 'varchar', 'length' => '25', 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'date_format', 'date_format', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'vat', 'vat', array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_change_field($ret, 'invoice_templates', 'pay_limit', 'pay_limit', array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_change_field($ret, 'invoice_templates', 'supplier_company_name', 'supplier_company_name', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_street', 'supplier_street', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_building_number', 'supplier_building_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_zipcode', 'supplier_zipcode', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_city', 'supplier_city', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_country', 'supplier_country', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_phone', 'supplier_phone', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_fax', 'supplier_fax', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_email', 'supplier_email', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_web', 'supplier_web', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_coc_number', 'supplier_coc_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  db_change_field($ret, 'invoice_templates', 'supplier_vat_number', 'supplier_vat_number', array('type' => 'varchar', 'length' => 100, 'not null' => FALSE));
+  
+  return $ret; // Array with query results.
+}
+
+/**
+ * Implementation of hook_update_N()
+ * 
+ * @return array Array with query results
+ */
+function invoice_update_2() {
+  $ret = array(); // Array to which query results will be added.
+  
+  db_add_field($ret, 'invoice_templates', 'display_column_vat', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_field($ret, 'invoice_templates', 'display_column_exunitcost', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
+  db_add_field($ret, 'invoice_templates', 'display_column_incunitcost', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
+  db_add_field($ret, 'invoice_templates', 'display_column_extotal', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
+  db_add_field($ret, 'invoice_templates', 'display_column_inctotal', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1));
+  
+  return $ret; // Array with query results.
+}
+
+/**
+ * Implementation of hook_update_N()
+ * 
+ * @return array Array with query results
+ */
+function invoice_update_3() {
+  $ret = array(); // Array to which query results will be added.
+  
+  if (is_null(variable_get('invoice_invoice_number_zerofill', NULL))) {
+    variable_set('invoice_invoice_number_zerofill', 4);
+  }
+  
+  if (is_null(variable_get('invoice_invoice_number_prefix', NULL))) {
+    variable_set('invoice_invoice_number_prefix', '%Y');
+  }
+  
+  db_add_field($ret, 'invoice_invoices', 'leading_zeros', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
+  db_add_field($ret, 'invoice_invoices', 'prefix', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE));
+  
+  return $ret; // Array with query results.
+}
+
+/**
+ * Implementation of hook_update_N()
+ * 
+ * This update fixes a privacy issue
+ * 
+ * @return array Array with query results
+ */
+function invoice_update_4() {
+
+  _make_sure_node_promote_flag_is_off();
+
+  // Make already created invoice nodes secure
+  db_query("UPDATE {node} SET promote=0 WHERE type='invoice'");
+  
+  return array();
+}
+
+/**
+ * Implementation of hook_update_N()
+ * 
+ * @return array Array with query results
+ */
+function invoice_update_5() {
+  // If these settings are not set already, set the default values. 
+  
+  $var1 = variable_get('invoice_display_column_vat', NULL);
+  $var2 = variable_get('invoice_display_column_exunitcost', NULL);
+  $var3 = variable_get('invoice_display_column_incunitcost', NULL);
+  $var4 = variable_get('invoice_display_column_extotal', NULL);
+  $var5 = variable_get('invoice_display_column_inctotal', NULL);
+  
+  if (is_null($var1) && is_null($var2) && is_null($var3) && is_null($var4) && is_null($var5)) {
+    variable_set('invoice_display_column_vat', 0);
+    variable_set('invoice_display_column_exunitcost', 1);
+    variable_set('invoice_display_column_incunitcost', 1);
+    variable_set('invoice_display_column_extotal', 1);
+    variable_set('invoice_display_column_inctotal', 1);    
+  }  
+  
+  return array();
+}
+
+function invoice_update_6() {
+  $ret = array();
+  db_create_table(
+    $ret,
+    'invoice_access_users',
+    array(
+      'description' => t('Matches UIDs from the {users} table to NIDs from the {node} table to determine which users should have access to a given invoice'),
+      'fields' => array(
+        'uid' => array(
+          'description' => t('The UID from the {users} table'),
+          'type' => 'int',
+          'not null' => TRUE,
+          'unsigned' => TRUE,
+        ),
+        'nid' => array(
+          'description' => t('The NID from the {node} table'),
+          'type' => 'int',
+          'not null' => TRUE,
+          'unsigned' => TRUE,
+        ),
+      ),
+      'primary key' => array('uid', 'nid'),
+    )
+  );
+  return $ret;
+}
+
+/**
+ * Implementation of hook_schema()
+ *
+ * @return array
+ */
+function invoice_schema() {
+  
+  $schema['invoice_customers'] = array(
+    'fields' => array(
+      'cid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+      'customer_number'  => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'company_name'     => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'firstname'        => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'lastname'         => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'street'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'building_number'  => array('type' => 'varchar', 'length' => 15, 'not null' => FALSE),
+      'zipcode'          => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
+      'city'             => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'country'          => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'coc_number'       => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
+      'vat_number'       => array('type' => 'varchar', 'length' => 25, 'not null' => FALSE),
+      'description'      => array('type' => 'text', 'not null' => FALSE),
+      'invoice_id'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+    ),
+    'primary key'        => array('cid'),
+    'unique keys'        => array(),
+    'indexes' => array(
+      'invoice_id'       => array('invoice_id'),
+      'customer_number'  => array('customer_number'),
+    ),
+  );
+  
+  $schema['invoice_invoices'] = array(
+    'fields' => array(
+      'iid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+      'nid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'leading_zeros'    => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'prefix'           =>  array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'description'      => array('type' => 'text', 'not null' => FALSE),
+      'tid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'pay_limit'        => array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'pay_status'       => array('type' => 'varchar', 'length' => 10, 'not null' => TRUE, 'default' => 'unpaid'),
+      'uid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE),
+    ),
+    'primary key'        => array('iid'),
+    'unique keys' => array(
+      'nid'             => array('nid'),
+    ),
+    'indexes' => array(
+      'tid'              => array('tid'),
+      'uid'              => array('uid'),
+    ),
+  );
+  
+  $schema['invoice_items'] = array(
+   'fields' => array(
+      'iid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+      'description'      => array('type' => 'text', 'size' => 'medium', 'not null' => FALSE),
+      'quantity'         => array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0),
+      'unitcost'         => array('type' => 'float', 'size' => 'big', 'not null' => TRUE, 'default' => 0),
+      'vat'              => array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'weight'           => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'invoice_id'       => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'uid'              => array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE),
+      'created'          => array('type' => 'datetime', 'not null' => TRUE),
+    ),
+    'primary key'        => array('iid'),
+    'unique keys'        => array(),
+    'indexes' => array(
+      'invoice_id'       => array('invoice_id'),
+      'uid'              => array('uid'),
+    ),
+  );
+
+  $schema['invoice_templates'] = array(
+    'fields' => array(
+      'tid'              => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+      'name'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'locale'           => array('type' => 'varchar', 'length' => '25', 'not null' => FALSE),
+      'date_format'      => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'vat'              => array('type' => 'float', 'size' => 'big', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'pay_limit'        => array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'supplier_company_name'      => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_street'            => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_building_number'   => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_zipcode'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_city'              => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_country'           => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_phone'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_fax'               => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_email'             => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_web'               => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_coc_number'        => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'supplier_vat_number'        => array('type' => 'varchar', 'length' => 100, 'not null' => FALSE),
+      'display_column_vat'         => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'display_column_exunitcost'  => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
+      'display_column_incunitcost' => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
+      'display_column_extotal'     => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
+      'display_column_inctotal'    => array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 1),
+    ),
+    'primary key'        => array('tid'),
+    'unique keys' => array(
+      'name'             => array('name'),
+    ),
+    'indexes'            => array(),
+  );
+  
+  $schema['invoice_access_users'] = array (
+    'description' => t('Matches UIDs from the {users} table to NIDs from the {node} table to determine which users should have access to a given invoice'),
+    'fields' => array (
+      'uid' => array (
+        'description' => t('The UID from the {users} table'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'unsigned' => TRUE,
+      ),
+      'nid' => array (
+        'description' => t('The NID from the {node} table'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'unsigned' => TRUE,
+      ),
+    ),
+    'primary key' => array('uid', 'nid'),
+  );
+  
+  return $schema;
+}
Index: invoice.module
===================================================================
--- invoice.module	(revision 1)
+++ invoice.module	(working copy)
@@ -1,27 +1,27 @@
-<?php
-// $Id: invoice.module,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
-
-/**
- * @file
- * Invoice module
- * 
- * This module was developed by Platina Designs, http://www.platinadesigns.nl
- *
- * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
- */
-
-// Set locale so money has the right format for the preferred culture
+<?php
+// $Id: invoice.module,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
+
+/**
+ * @file
+ * Invoice module
+ * 
+ * This module was developed by Platina Designs, http://www.platinadesigns.nl
+ *
+ * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
+ */
+
+// Set locale so money has the right format for the preferred culture
 setlocale(LC_MONETARY, variable_get('invoice_locale', 'en_US.utf8'));
-
-// Include files
-
-// Ajax functions
-require_once dirname(__FILE__) .'/invoice_ajax.inc';
-// Form functions
-require_once dirname(__FILE__) .'/invoice_form.inc';
-// Helper functions
-require_once dirname(__FILE__) .'/invoice_helpers.inc';
-
+
+// Include files
+
+// Ajax functions
+require_once dirname(__FILE__) .'/invoice_ajax.inc';
+// Form functions
+require_once dirname(__FILE__) .'/invoice_form.inc';
+// Helper functions
+require_once dirname(__FILE__) .'/invoice_helpers.inc';
+
 /**
  * Implementation of hook_node_info()
  */
@@ -38,312 +38,315 @@
     )
   );
 }
-
-/**
- * Implementation of hook_menu()
- */
-function invoice_menu() {
-  $items = array();
-  $items['invoices'] = array(
-    'title' => 'Invoices',
-    'page callback' => 'invoice_invoices',
-    'access arguments' => array('access invoices'),
-  );
-  $items['invoice/list'] = array(
-    'title' => 'List invoices',
+
+/**
+ * Implementation of hook_menu()
+ */
+function invoice_menu() {
+  $items = array();
+  $items['invoices'] = array(
+    'title' => 'Invoices',
+    'page callback' => 'invoice_invoices',
+    'access arguments' => array('access invoices'),
+  );
+  $items['invoice/list'] = array(
+    'title' => 'List invoices',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'access arguments' => array('access invoices'),
+    'access arguments' => array('access invoices'),
   );
   $items['invoice/list/customers'] = array(
     'title' => 'List customers',
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('access invoices'),
-  );
-  $items['invoice/add/invoice'] = array(
-    'title' => 'Add invoice',
+  );
+  $items['invoice/add/invoice'] = array(
+    'title' => 'Add invoice',
     'page callback' => 'invoice_add_invoice',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
   );  
   $items['invoice/add/customer'] = array(
     'title' => 'Add customer',
     'page callback' => 'invoice_add_customer',    
     'access arguments' => array('administer customers'),
     'type' => MENU_CALLBACK,
-  );
-  $items['invoice/edit/invoice/%'] = array(
-    'title' => 'Edit invoice',
-    'page callback' => 'invoice_edit_invoice',
-    'page arguments' => array(2),
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/set/template'] = array(
-    'title' => 'Edit invoice',
-    'page callback' => 'invoice_set_template',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/print/%'] = array(
-    'title' => 'Invoice in HTML print format',
-    'page callback' => 'invoice_view_print',
-    'page arguments' => array(2),
-    'access arguments' => array('access invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/pdf/%'] = array(
-    'title' => 'Invoice in PDF format',
-    'page callback' => 'invoice_view_pdf',
-    'page arguments' => array(2),
-    'access arguments' => array('access invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/set/pay_status/%/%'] = array(
-    'title' => 'Set invoice pay status',
-    'page callback' => 'invoice_set_pay_status',
-    'page arguments' => array(3, 4),
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/search/customer'] = array(
-    'title' => 'Search customer',
-    'page callback' => 'invoice_search_customer',
-    'page arguments' => array(3),
-    'access arguments' => array('administer customers'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/get/customer_info'] = array(
-    'title' => 'Get customer info',
-    'page callback' => 'invoice_get_customer_info',
-    'access arguments' => array('administer customers'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/delete/invoice/%'] = array(
-    'page callback' => 'invoice_delete_invoice',
-    'page arguments' => array(2),
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
   );
-  $items['invoice/save/item'] = array(
-    'title' => 'Save item',
-    'page callback' => 'invoice_save_item',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/edit/item'] = array(
-    'title' => 'Edit item',
-    'page callback' => 'invoice_edit_item',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['invoice/delete/item'] = array(
-    'title' => 'Delete item',
-    'page callback' => 'invoice_delete_item',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  $items['admin/settings/invoice'] = array(
-    'title' => 'Invoice',
-    'page callback' => 'invoice_settings',    
-    'access arguments' => array('administer invoices'),
-    'description' => 'Create and manage invoices.',
-    'type' => MENU_NORMAL_ITEM,
-  );
-  $items['invoice/installed_locales'] = array(
-    'title' => 'Installed locales on your system',
-    'page callback' => 'invoice_installed_locales',    
-    'access arguments' => array('administer invoices'),
-    'type' => MENU_CALLBACK,
-  );
-  return $items;
-}
-
-/**
- * Implementation of hook_perm()
- */
-function invoice_perm() {
-  return array('access invoices', 'administer invoices', 'administer own invoices');
-}
-
-/**
- * Implementation of hook_access()
- *
- * @param string $op
- * @param object $node
- * @param object $account
- * @return boolean
- */
-function invoice_access($op, $node, $account) {
-  if ($op == 'view') {
-    return user_access('access invoices', $account);
-  }
-  if ($op == 'create') {
-    return user_access('administer invoices', $account);
-  }
-  if ($op == 'update') {
-    if (user_access('administer invoices', $account) || (user_access('administer own invoices', $account) && ($account->uid == $node->uid))) {
-      return TRUE;
-    }
-  }
-  if ($op == 'delete') {
-    if (user_access('administer invoices', $account) || (user_access('administer own invoices', $account) && ($account->uid == $node->uid))) {
-      return TRUE;
-    }
-  }
-}
-
-/**
- * Implementation of hook_theme()
- *
- * @param unknown_type $existing
- * @param unknown_type $type
- * @param unknown_type $theme
- * @param unknown_type $path
- * @return array
- */
-function invoice_theme($existing, $type, $theme, $path) {
-  return array(
-    'invoice_body' => array(
-      'arguments' => array('node' => NULL, 'type' => NULL),
-    ),
-    'invoice_markup' => array(
-      'arguments' => array('s_fieldname' => NULL, 'value' => NULL, 's_title' => NULL),
-    ),
-    'invoice_table' => array(
-      'arguments' => array('header' => NULL, 'rows' => NULL, 'attributes' => NULL, 'caption' => NULL),
-    ),
-  );
-}
-
-/**
- * Implementation of hook_load()
- *
- * @param object $node
- * @return mixed
- */
-function invoice_load($node) {
-  (object) $o_additions;
- 
-  // Get all invoices information
-  $o_invoice = db_fetch_object(db_query("SELECT *,ii.iid as invoice_number,ii.leading_zeros AS leading_zeros, ii.prefix AS prefix,
-    ii.description AS invoice_description, ii.pay_limit AS pay_limit, ic.description AS customer_description, t.name as template
-    FROM {invoice_invoices} ii
-    LEFT JOIN {invoice_customers} ic ON ic.invoice_id=ii.iid
-    LEFT JOIN {invoice_templates} t ON ii.tid=t.tid
-    WHERE nid=%d
-    GROUP BY ii.iid",
-    $node->nid
-  ));
-  
-  $a_totals = _invoice_get_invoice_totals($o_invoice->invoice_number);
-  
-  $o_invoice->extotal = $a_totals['extotal'];
-  $o_invoice->inctotal = $a_totals['inctotal'];
-  $o_invoice->vattotal = $a_totals['vattotal'];
-
-  // Determine template to use
-  $template = !empty($o_invoice->template) ? $o_invoice->template : variable_get('invoice_default_template', 'default');
-  
-  // Set locale so money has the right format for the preferred culture
-  if ($locale = _invoice_get_variable($template, 'locale')) {
-    setlocale(LC_MONETARY, $locale);
-  }
-  
-  // Calculate vat totals per different VAT percentage
-  $a_vattotals = array();
-  
-  $result = db_query("SELECT vat, (quantity*unitcost)*((vat / 100) +1) * (1 - (1 / ((vat / 100) +1))) as vattotal
-    FROM {invoice_items}
-    WHERE invoice_id=%d",
-    $o_invoice->invoice_number
-  );
-  
-  // SUM all vat totals per different VAT percentage
-  while ($row = db_fetch_object($result)) {
-    if (!isset($a_vattotals[$row->vat])) {
-      $a_vattotals[$row->vat] = array(
-        'vattotal' => $row->vattotal,
-      );  
-    }
-    else {
-      $a_vattotals[$row->vat]['vattotal'] += $row->vattotal;
-    }
-  }
-  
-  // Round every total per different VAT percentage
-  // and add a formatted version
-  foreach ($a_vattotals as $key => &$total) {
-    $total['vattotal'] = _invoice_round($total['vattotal'], 2);
-    $total['formatted_vattotal'] = _invoice_format_money($total['vattotal'], 2);
-  }
-
-  // Set totals
-  $extotal = _invoice_round($o_invoice->extotal, 2);
-  $inctotal = _invoice_round($o_invoice->inctotal, 2);  
-  $vattotal = _invoice_round($o_invoice->vattotal, 2);
-
-  // Add general invoice information to the node object 
-  $o_additions->invoice = array(
-    'invoice_number' => $o_invoice->invoice_number,
-    'formatted_invoice_number' => _invoice_get_formatted_invoice_number($o_invoice->invoice_number),
-    'invoice_number_zerofill' => $o_invoice->leading_zeros,
-    'invoice_number_prefix' => $o_invoice->prefix,
-    'description' => $o_invoice->invoice_description,
-    'vat' => $a_vattotals,
-    'pay_status' => $o_invoice->pay_status,
-    'pay_limit' => $o_invoice->pay_limit,
-    'template' => $template,
-    'extotal' => $extotal,
-    'inctotal' => $inctotal,
-    'formatted_vattotal' => _invoice_format_money($vattotal, 2),
-    'formatted_extotal' => _invoice_format_money($extotal, 2),
-    'formatted_inctotal' => _invoice_format_money($inctotal, 2),
-    'formatted_created' => format_date($node->created, 'custom', _invoice_get_variable($template, 'date_format')),
-  );
-  
-  // Add customer information to the node object 
-  $o_additions->customer = array(
-    'cid' => $o_invoice->cid,
-    'customer_number' => $o_invoice->customer_number,
-    'name' => $name,
-    'company_name' => $o_invoice->company_name,
-    'firstname' => $o_invoice->firstname,
-    'lastname' => $o_invoice->lastname,
-    'fullname' => $o_invoice->lastname . (!empty($o_invoice->firstname) ? ', '. $o_invoice->firstname : ''),
-    'street' => $o_invoice->street,
-    'building_number' => $o_invoice->building_number,
-    'zipcode' => $o_invoice->zipcode,
-    'city' => $o_invoice->city,
-    'country' => $o_invoice->country,
-    'coc_number' => $o_invoice->coc_number,
-    'vat_number' => $o_invoice->vat_number,
-    'description' => $o_invoice->customer_description,
-  );
-  
-  // Add invoices items to the node object
-  $o_additions->invoice_items = array();
-  
-  $result = db_query("SELECT * FROM {invoice_items} WHERE invoice_id=%d ORDER BY created ASC, weight ASC", $o_invoice->invoice_number);
-  while ($row = db_fetch_object($result)) {
-    
-    // Add invoice item row to the array 
-    $o_additions->invoice_items[] = array(
-      'iid' => $row->iid,
-      'description' => $row->description,
-      'quantity' => $row->quantity,
-      'unitcost' => $row->unitcost,
-      'vat' => $row->vat,
-      'formatted_exunitcost' => _invoice_round_and_format_money($row->unitcost, 3),
-      'formatted_incunitcost' => _invoice_round_and_format_money($row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
-      'formatted_extotal' => _invoice_round_and_format_money($row->quantity * $row->unitcost, 2),
-      'formatted_inctotal' => _invoice_round_and_format_money($row->quantity * $row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2), 
-    );
-  }
-      
-  return $o_additions;
-}
+  $items['invoice/edit/invoice/%'] = array(
+    'title' => 'Edit invoice',
+    'page callback' => 'invoice_edit_invoice',
+    'page arguments' => array(2),
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/set/template'] = array(
+    'title' => 'Edit invoice',
+    'page callback' => 'invoice_set_template',    
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/print/%'] = array(
+    'title' => 'Invoice in HTML print format',
+    'page callback' => 'invoice_view_print',
+    'page arguments' => array(2),
+    'access arguments' => array('access invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/pdf/%'] = array(
+    'title' => 'Invoice in PDF format',
+    'page callback' => 'invoice_view_pdf',
+    'page arguments' => array(2),
+    'access arguments' => array('access invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/set/pay_status/%/%'] = array(
+    'title' => 'Set invoice pay status',
+    'page callback' => 'invoice_set_pay_status',
+    'page arguments' => array(3, 4),
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/search/customer'] = array(
+    'title' => 'Search customer',
+    'page callback' => 'invoice_search_customer',
+    'page arguments' => array(3),
+    'access arguments' => array('administer customers'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/get/customer_info'] = array(
+    'title' => 'Get customer info',
+    'page callback' => 'invoice_get_customer_info',
+    'access arguments' => array('administer customers'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/delete/invoice/%'] = array(
+    'page callback' => 'invoice_delete_invoice',
+    'page arguments' => array(2),
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/save/item'] = array(
+    'title' => 'Save item',
+    'page callback' => 'invoice_save_item',    
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/edit/item'] = array(
+    'title' => 'Edit item',
+    'page callback' => 'invoice_edit_item',    
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/delete/item'] = array(
+    'title' => 'Delete item',
+    'page callback' => 'invoice_delete_item',    
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/settings/invoice'] = array(
+    'title' => 'Invoice',
+    'page callback' => 'invoice_settings',    
+    'access arguments' => array('administer invoices'),
+    'description' => 'Create and manage invoices.',
+    'type' => MENU_NORMAL_ITEM,
+  );
+  $items['invoice/installed_locales'] = array(
+    'title' => 'Installed locales on your system',
+    'page callback' => 'invoice_installed_locales',    
+    'access arguments' => array('administer invoices'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['invoice/autocomplete/users_multiple'] = array(
+	'title' => '',
+	'page callback' => 'invoice_autocomplete_users_multiple',
+	'access arguments' => array('administer invoices'),
+	'type' => MENU_CALLBACK,
+  );
+  return $items;
+}
 
 /**
+ * Implementation of hook_perm()
+ */
+function invoice_perm() {
+  return array('access invoices', 'administer invoices', 'administer own invoices');
+}
+
+/**
+ * Implementation of hook_access()
+ *
+ * @param string $op
+ * @param object $node
+ * @param object $account
+ * @return boolean
+ */
+function invoice_access($op, $node, $account) {
+  if ($op == 'create') {
+    return user_access('administer invoices', $account);
+  }
+  if ($op == 'update') {
+    if (user_access('administer invoices', $account) || (user_access('administer own invoices', $account) && ($account->uid == $node->uid))) {
+      return TRUE;
+    }
+  }
+  if ($op == 'delete') {
+    if (user_access('administer invoices', $account) || (user_access('administer own invoices', $account) && ($account->uid == $node->uid))) {
+      return TRUE;
+    }
+  }
+}
+
+/**
+ * Implementation of hook_theme()
+ *
+ * @param unknown_type $existing
+ * @param unknown_type $type
+ * @param unknown_type $theme
+ * @param unknown_type $path
+ * @return array
+ */
+function invoice_theme($existing, $type, $theme, $path) {
+  return array(
+    'invoice_body' => array(
+      'arguments' => array('node' => NULL, 'type' => NULL),
+    ),
+    'invoice_markup' => array(
+      'arguments' => array('s_fieldname' => NULL, 'value' => NULL, 's_title' => NULL),
+    ),
+    'invoice_table' => array(
+      'arguments' => array('header' => NULL, 'rows' => NULL, 'attributes' => NULL, 'caption' => NULL),
+    ),
+  );
+}
+
+/**
+ * Implementation of hook_load()
+ *
+ * @param object $node
+ * @return mixed
+ */
+function invoice_load($node) {
+  (object) $o_additions;
+ 
+  // Get all invoices information
+  $o_invoice = db_fetch_object(db_query("SELECT *,ii.iid as invoice_number,ii.leading_zeros AS leading_zeros, ii.prefix AS prefix,
+    ii.description AS invoice_description, ii.pay_limit AS pay_limit, ic.description AS customer_description, t.name as template
+    FROM {invoice_invoices} ii
+    LEFT JOIN {invoice_customers} ic ON ic.invoice_id=ii.iid
+    LEFT JOIN {invoice_templates} t ON ii.tid=t.tid
+    WHERE nid=%d
+    GROUP BY ii.iid",
+    $node->nid
+  ));
+  
+  $a_totals = _invoice_get_invoice_totals($o_invoice->invoice_number);
+  
+  $o_invoice->extotal = $a_totals['extotal'];
+  $o_invoice->inctotal = $a_totals['inctotal'];
+  $o_invoice->vattotal = $a_totals['vattotal'];
+
+  // Determine template to use
+  $template = !empty($o_invoice->template) ? $o_invoice->template : variable_get('invoice_default_template', 'default');
+  
+  // Set locale so money has the right format for the preferred culture
+  if ($locale = _invoice_get_variable($template, 'locale')) {
+    setlocale(LC_MONETARY, $locale);
+  }
+  
+  // Calculate vat totals per different VAT percentage
+  $a_vattotals = array();
+  
+  $result = db_query("SELECT vat, (quantity*unitcost)*((vat / 100) +1) * (1 - (1 / ((vat / 100) +1))) as vattotal
+    FROM {invoice_items}
+    WHERE invoice_id=%d",
+    $o_invoice->invoice_number
+  );
+  
+  // SUM all vat totals per different VAT percentage
+  while ($row = db_fetch_object($result)) {
+    if (!isset($a_vattotals[$row->vat])) {
+      $a_vattotals[$row->vat] = array(
+        'vattotal' => $row->vattotal,
+      );  
+    }
+    else {
+      $a_vattotals[$row->vat]['vattotal'] += $row->vattotal;
+    }
+  }
+  
+  // Round every total per different VAT percentage
+  // and add a formatted version
+  foreach ($a_vattotals as $key => &$total) {
+    $total['vattotal'] = _invoice_round($total['vattotal'], 2);
+    $total['formatted_vattotal'] = _invoice_format_money($total['vattotal'], 2);
+  }
+
+  // Set totals
+  $extotal = _invoice_round($o_invoice->extotal, 2);
+  $inctotal = _invoice_round($o_invoice->inctotal, 2);  
+  $vattotal = _invoice_round($o_invoice->vattotal, 2);
+
+  // Add general invoice information to the node object 
+  $o_additions->invoice = array(
+    'invoice_number' => $o_invoice->invoice_number,
+    'formatted_invoice_number' => _invoice_get_formatted_invoice_number($o_invoice->invoice_number),
+    'invoice_number_zerofill' => $o_invoice->leading_zeros,
+    'invoice_number_prefix' => $o_invoice->prefix,
+    'description' => $o_invoice->invoice_description,
+    'vat' => $a_vattotals,
+    'pay_status' => $o_invoice->pay_status,
+    'pay_limit' => $o_invoice->pay_limit,
+    'template' => $template,
+    'extotal' => $extotal,
+    'inctotal' => $inctotal,
+    'formatted_vattotal' => _invoice_format_money($vattotal, 2),
+    'formatted_extotal' => _invoice_format_money($extotal, 2),
+    'formatted_inctotal' => _invoice_format_money($inctotal, 2),
+    'formatted_created' => format_date($node->created, 'custom', _invoice_get_variable($template, 'date_format')),
+  );
+  
+  // Add customer information to the node object 
+  $o_additions->customer = array(
+    'cid' => $o_invoice->cid,
+    'customer_number' => $o_invoice->customer_number,
+    'name' => $name,
+    'company_name' => $o_invoice->company_name,
+    'firstname' => $o_invoice->firstname,
+    'lastname' => $o_invoice->lastname,
+    'fullname' => $o_invoice->lastname . (!empty($o_invoice->firstname) ? ', '. $o_invoice->firstname : ''),
+    'street' => $o_invoice->street,
+    'building_number' => $o_invoice->building_number,
+    'zipcode' => $o_invoice->zipcode,
+    'city' => $o_invoice->city,
+    'country' => $o_invoice->country,
+    'coc_number' => $o_invoice->coc_number,
+    'vat_number' => $o_invoice->vat_number,
+    'description' => $o_invoice->customer_description,
+  );
+  
+  // Add invoices items to the node object
+  $o_additions->invoice_items = array();
+  
+  $result = db_query("SELECT * FROM {invoice_items} WHERE invoice_id=%d ORDER BY created ASC, weight ASC", $o_invoice->invoice_number);
+  while ($row = db_fetch_object($result)) {
+    
+    // Add invoice item row to the array 
+    $o_additions->invoice_items[] = array(
+      'iid' => $row->iid,
+      'description' => $row->description,
+      'quantity' => $row->quantity,
+      'unitcost' => $row->unitcost,
+      'vat' => $row->vat,
+      'formatted_exunitcost' => _invoice_round_and_format_money($row->unitcost, 3),
+      'formatted_incunitcost' => _invoice_round_and_format_money($row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
+      'formatted_extotal' => _invoice_round_and_format_money($row->quantity * $row->unitcost, 2),
+      'formatted_inctotal' => _invoice_round_and_format_money($row->quantity * $row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2), 
+    );
+  }
+      
+  return $o_additions;
+}
+
+/**
  * Implementation of hook_nodeapi()
  *
  * @param object $node
@@ -352,165 +355,165 @@
  * @param string $page
  */
 function invoice_nodeapi(&$node, $op, $teaser, $page) {
-  switch ($op) {
-    case "presave":
-      if ($node->type == 'invoice') {
-        // If true we are creating a new invoice
-        if (intval($node->invoice_number) == 0) {
-          // Get new invoice number
-          if (intval($node->user_defined_invoice_number) > 0) {
-            $node->invoice_number = $node->user_defined_invoice_number;
-          }
-          else {
-            $node->invoice_number = _invoice_get_new_invoice_number();  
-          }
-        }
-        
-        // Save the title, this must happen when creating AND editing a node because otherwise
-        // the pathauto module will give an error
-        if (intval($node->invoice_number) > 0) {
-          $node->title = t('Invoice') .' #'. _invoice_get_formatted_invoice_number($node->invoice_number, $node);
-        }
-        
-        // Get customer number
-        if (!empty($node->company_name)) {
-          $customer_number = db_result(db_query("SELECT customer_number FROM {invoice_customers}
-            WHERE company_name='%s' AND country='%s' LIMIT 1",
-            $node->company_name,
-            $node->country
-          ));
-        }
-        elseif (!empty($node->lastname)) {
-          $customer_number = db_result(db_query("SELECT customer_number FROM {invoice_customers}
-            WHERE lastname='%s' AND zipcode='%s' AND building_number='%s' LIMIT 1",
-            $node->lastname,
-            $node->zipcode,
-            $node->building_number
-          ));
-        }
-        
-        // If customer number is still empty, get a new one
-        if (empty($customer_number)) {
-          $customer_number = 1 + db_result(db_query("SELECT MAX(customer_number) FROM {invoice_customers}"));
-        }
-        
-        // Add customer number to the node object
-        $node->customer_number = $customer_number;
-      }
-      break;
+  switch ($op) {
+    case "presave":
+      if ($node->type == 'invoice') {
+        // If true we are creating a new invoice
+        if (intval($node->invoice_number) == 0) {
+          // Get new invoice number
+          if (intval($node->user_defined_invoice_number) > 0) {
+            $node->invoice_number = $node->user_defined_invoice_number;
+          }
+          else {
+            $node->invoice_number = _invoice_get_new_invoice_number();  
+          }
+        }
+        
+        // Save the title, this must happen when creating AND editing a node because otherwise
+        // the pathauto module will give an error
+        if (intval($node->invoice_number) > 0) {
+          $node->title = t('Invoice') .' #'. _invoice_get_formatted_invoice_number($node->invoice_number, $node);
+        }
+        
+        // Get customer number
+        if (!empty($node->company_name)) {
+          $customer_number = db_result(db_query("SELECT customer_number FROM {invoice_customers}
+            WHERE company_name='%s' AND country='%s' LIMIT 1",
+            $node->company_name,
+            $node->country
+          ));
+        }
+        elseif (!empty($node->lastname)) {
+          $customer_number = db_result(db_query("SELECT customer_number FROM {invoice_customers}
+            WHERE lastname='%s' AND zipcode='%s' AND building_number='%s' LIMIT 1",
+            $node->lastname,
+            $node->zipcode,
+            $node->building_number
+          ));
+        }
+        
+        // If customer number is still empty, get a new one
+        if (empty($customer_number)) {
+          $customer_number = 1 + db_result(db_query("SELECT MAX(customer_number) FROM {invoice_customers}"));
+        }
+        
+        // Add customer number to the node object
+        $node->customer_number = $customer_number;
+      }
+      break;
   }
-}
-
-/**
- * Invoice settings
- */
-function invoice_settings() {
-  
-  // A little test to see if the function _invoice_round() rounds well on every server
-  if (_invoice_round(38.675, 2) != 38.68) {
-    drupal_set_message(t('TEST: The answer of _invoice_round(38.675, 2) must be 38.68, but is @answer! This problem is maybe caused by your PHP version.', array('@answer' => _invoice_round(38.675, 2))), 'error');
-  }
-  
-  $content = '';  
-  $content = drupal_get_form('invoice_settings_form');
-  return $content;
-}
-
-/**
- * Submit function for the settings form
- */
-function invoice_settings_form_submit(&$form_state, $form) {
-  $fv =& $form['values'];
-  
-  // Invoice specific settings
-  variable_set('invoice_locale', $fv['locale']);
-  variable_set('invoice_date_format', $fv['date_format']);
-  variable_set('invoice_vat', $fv['vat']);
-  variable_set('invoice_pay_limit', $fv['pay_limit']);
-  variable_set('invoice_invoice_number_zerofill', $fv['invoice_number_zerofill']);
-  variable_set('invoice_invoice_number_prefix', $fv['invoice_number_prefix']);
-  variable_set('invoice_default_template', $fv['default_template']);
-
-  // Display columns specific settings
-  variable_set('invoice_display_column_vat', $fv['display_column_vat']);
-  variable_set('invoice_display_column_exunitcost', $fv['display_column_exunitcost']);
-  variable_set('invoice_display_column_incunitcost', $fv['display_column_incunitcost']);
-  variable_set('invoice_display_column_extotal', $fv['display_column_extotal']);
-  variable_set('invoice_display_column_inctotal', $fv['display_column_inctotal']);
-  
-  // Supplier specific settings
-  variable_set('invoice_supplier_company_name', $fv['supplier_company_name']);
-  variable_set('invoice_supplier_street', $fv['supplier_street']);
-  variable_set('invoice_supplier_building_number', $fv['supplier_building_number']);
-  variable_set('invoice_supplier_zipcode', $fv['supplier_zipcode']);
-  variable_set('invoice_supplier_city', $fv['supplier_city']);
-  variable_set('invoice_supplier_country', $fv['supplier_country']);
-  variable_set('invoice_supplier_phone', $fv['supplier_phone']);
-  variable_set('invoice_supplier_fax', $fv['supplier_fax']);
-  variable_set('invoice_supplier_email', $fv['supplier_email']);
-  variable_set('invoice_supplier_web', $fv['supplier_web']);
-  variable_set('invoice_supplier_coc_number', $fv['supplier_coc_number']);
-  variable_set('invoice_supplier_vat_number', $fv['supplier_vat_number']);
-  
-  $a_templates = _invoice_get_templates();
-  
-  foreach ($a_templates as $s_template) {
-    $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_templates} WHERE name='%s'", $s_template));
-    if ($count == 0) {
-      db_query("INSERT INTO {invoice_templates} (name) VALUES ('%s')", $s_template);
-    }
-    
-    
-    // Numeric fields in this query will become a zero if nothing is filled in, instead of the overloading system.
-    // So numeric fields that are empty will take over the general setting and update that in the database for this template.
-    db_query("UPDATE {invoice_templates} SET locale='%s', date_format='%s', vat=%d, pay_limit=%d,
-      supplier_company_name='%s', supplier_street='%s', supplier_building_number='%s', supplier_zipcode='%s', supplier_city='%s',
-      supplier_country='%s', supplier_phone='%s', supplier_fax='%s', supplier_email='%s', supplier_web='%s', supplier_coc_number='%s',
-      supplier_vat_number='%s', display_column_vat=%d, display_column_exunitcost=%d, display_column_incunitcost=%d,
-      display_column_extotal=%d, display_column_inctotal=%d
-      WHERE name='%s'",
-      $fv[$s_template .'_locale'],
-      $fv[$s_template .'_date_format'],      
-      $fv[$s_template .'_vat'] != '' ? $fv[$s_template .'_vat'] : $fv['vat'],
-      $fv[$s_template .'_pay_limit'] != '' ? $fv[$s_template .'_pay_limit'] : $fv['pay_limit'],
-      $fv[$s_template .'_supplier_company_name'],
-      $fv[$s_template .'_supplier_street'],
-      $fv[$s_template .'_supplier_building_number'],
-      $fv[$s_template .'_supplier_zipcode'],
-      $fv[$s_template .'_supplier_city'],
-      $fv[$s_template .'_supplier_country'],
-      $fv[$s_template .'_supplier_phone'],
-      $fv[$s_template .'_supplier_fax'],
-      $fv[$s_template .'_supplier_email'],
-      $fv[$s_template .'_supplier_web'],
-      $fv[$s_template .'_supplier_coc_number'],
-      $fv[$s_template .'_supplier_vat_number'],
-      $count > 0 ? $fv[$s_template .'_display_column_vat'] : 0, // set default value if we deal with a new template
-      $count > 0 ? $fv[$s_template .'_display_column_exunitcost'] : 1, // set default value if we deal with a new template
-      $count > 0 ? $fv[$s_template .'_display_column_incunitcost'] : 1, // set default value if we deal with a new template
-      $count > 0 ? $fv[$s_template .'_display_column_extotal'] : 1, // set default value if we deal with a new template
-      $count > 0 ? $fv[$s_template .'_display_column_inctotal'] : 1, // set default value if we deal with a new template
-      $s_template
-    );
-  }
-    
-  drupal_set_message(t('Succesfully saved'));
-}
-
-/**
- * Overview of all invoices
- */
-function invoice_invoices() {
+}
 
+/**
+ * Invoice settings
+ */
+function invoice_settings() {
+  
+  // A little test to see if the function _invoice_round() rounds well on every server
+  if (_invoice_round(38.675, 2) != 38.68) {
+    drupal_set_message(t('TEST: The answer of _invoice_round(38.675, 2) must be 38.68, but is @answer! This problem is maybe caused by your PHP version.', array('@answer' => _invoice_round(38.675, 2))), 'error');
+  }
+  
+  $content = '';  
+  $content = drupal_get_form('invoice_settings_form');
+  return $content;
+}
+
+/**
+ * Submit function for the settings form
+ */
+function invoice_settings_form_submit(&$form_state, $form) {
+  $fv =& $form['values'];
+  
+  // Invoice specific settings
+  variable_set('invoice_locale', $fv['locale']);
+  variable_set('invoice_date_format', $fv['date_format']);
+  variable_set('invoice_vat', $fv['vat']);
+  variable_set('invoice_pay_limit', $fv['pay_limit']);
+  variable_set('invoice_invoice_number_zerofill', $fv['invoice_number_zerofill']);
+  variable_set('invoice_invoice_number_prefix', $fv['invoice_number_prefix']);
+  variable_set('invoice_default_template', $fv['default_template']);
+
+  // Display columns specific settings
+  variable_set('invoice_display_column_vat', $fv['display_column_vat']);
+  variable_set('invoice_display_column_exunitcost', $fv['display_column_exunitcost']);
+  variable_set('invoice_display_column_incunitcost', $fv['display_column_incunitcost']);
+  variable_set('invoice_display_column_extotal', $fv['display_column_extotal']);
+  variable_set('invoice_display_column_inctotal', $fv['display_column_inctotal']);
+  
+  // Supplier specific settings
+  variable_set('invoice_supplier_company_name', $fv['supplier_company_name']);
+  variable_set('invoice_supplier_street', $fv['supplier_street']);
+  variable_set('invoice_supplier_building_number', $fv['supplier_building_number']);
+  variable_set('invoice_supplier_zipcode', $fv['supplier_zipcode']);
+  variable_set('invoice_supplier_city', $fv['supplier_city']);
+  variable_set('invoice_supplier_country', $fv['supplier_country']);
+  variable_set('invoice_supplier_phone', $fv['supplier_phone']);
+  variable_set('invoice_supplier_fax', $fv['supplier_fax']);
+  variable_set('invoice_supplier_email', $fv['supplier_email']);
+  variable_set('invoice_supplier_web', $fv['supplier_web']);
+  variable_set('invoice_supplier_coc_number', $fv['supplier_coc_number']);
+  variable_set('invoice_supplier_vat_number', $fv['supplier_vat_number']);
+  
+  $a_templates = _invoice_get_templates();
+  
+  foreach ($a_templates as $s_template) {
+    $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_templates} WHERE name='%s'", $s_template));
+    if ($count == 0) {
+      db_query("INSERT INTO {invoice_templates} (name) VALUES ('%s')", $s_template);
+    }
+    
+    
+    // Numeric fields in this query will become a zero if nothing is filled in, instead of the overloading system.
+    // So numeric fields that are empty will take over the general setting and update that in the database for this template.
+    db_query("UPDATE {invoice_templates} SET locale='%s', date_format='%s', vat=%d, pay_limit=%d,
+      supplier_company_name='%s', supplier_street='%s', supplier_building_number='%s', supplier_zipcode='%s', supplier_city='%s',
+      supplier_country='%s', supplier_phone='%s', supplier_fax='%s', supplier_email='%s', supplier_web='%s', supplier_coc_number='%s',
+      supplier_vat_number='%s', display_column_vat=%d, display_column_exunitcost=%d, display_column_incunitcost=%d,
+      display_column_extotal=%d, display_column_inctotal=%d
+      WHERE name='%s'",
+      $fv[$s_template .'_locale'],
+      $fv[$s_template .'_date_format'],      
+      $fv[$s_template .'_vat'] != '' ? $fv[$s_template .'_vat'] : $fv['vat'],
+      $fv[$s_template .'_pay_limit'] != '' ? $fv[$s_template .'_pay_limit'] : $fv['pay_limit'],
+      $fv[$s_template .'_supplier_company_name'],
+      $fv[$s_template .'_supplier_street'],
+      $fv[$s_template .'_supplier_building_number'],
+      $fv[$s_template .'_supplier_zipcode'],
+      $fv[$s_template .'_supplier_city'],
+      $fv[$s_template .'_supplier_country'],
+      $fv[$s_template .'_supplier_phone'],
+      $fv[$s_template .'_supplier_fax'],
+      $fv[$s_template .'_supplier_email'],
+      $fv[$s_template .'_supplier_web'],
+      $fv[$s_template .'_supplier_coc_number'],
+      $fv[$s_template .'_supplier_vat_number'],
+      $count > 0 ? $fv[$s_template .'_display_column_vat'] : 0, // set default value if we deal with a new template
+      $count > 0 ? $fv[$s_template .'_display_column_exunitcost'] : 1, // set default value if we deal with a new template
+      $count > 0 ? $fv[$s_template .'_display_column_incunitcost'] : 1, // set default value if we deal with a new template
+      $count > 0 ? $fv[$s_template .'_display_column_extotal'] : 1, // set default value if we deal with a new template
+      $count > 0 ? $fv[$s_template .'_display_column_inctotal'] : 1, // set default value if we deal with a new template
+      $s_template
+    );
+  }
+    
+  drupal_set_message(t('Succesfully saved'));
+}
+
+/**
+ * Overview of all invoices
+ */
+function invoice_invoices() {
+
   $content = '';
 
   //Our header defenition
   $header = array(
     array('data' => t('Invoice #'), 'field' => 'ii.iid'),    
     array('data' => t('Customer'), 'field' => 'c.customer'),
-    array('data' => t('Total (ex)'), 'field' => 'extotal'),
+    array('data' => t('Total (ex)'), 'field' => 'extotal'),
     array('data' => t('Total (inc)'), 'field' => 'inctotal'),    
-    array('data' => t('Created'), 'field' => 'invoices.created'),
+    array('data' => t('Created'), 'field' => 'invoices.created'),
     array('data' => _invoice_get_icon('bullet_black', NULL, array('title' => t('sort by @s', array('@s' => t('Pay status'))))), 'field' => 'ii.pay_status'),
     t('Actions')
   );
@@ -520,15 +523,15 @@
     $_GET['sort'] = "desc";
   }
   
-  $query = "SELECT COUNT(*),ii.iid,ii.nid,ii.pay_limit,ii.pay_status,c.company_name,c.lastname,c.firstname,n.created,it.name as template
+  $query = "SELECT COUNT(*),ii.iid,ii.nid,ii.pay_limit,ii.pay_status,c.company_name,c.lastname,c.firstname,n.created,it.name as template
     FROM {invoice_invoices} ii
-    LEFT JOIN {node} n ON ii.nid=n.nid
+    LEFT JOIN {node} n ON ii.nid=n.nid
     LEFT JOIN {invoice_customers} c ON ii.iid=c.invoice_id
-    LEFT JOIN {invoice_templates} it ON ii.tid=it.tid
+    LEFT JOIN {invoice_templates} it ON ii.tid=it.tid
     GROUP BY ii.iid
-    ";
-  
-  //$query .= tablesort_sql($header);
+    ";
+  
+  //$query .= tablesort_sql($header);
   $query .= "ORDER BY nid DESC";
   
   $count_query = "SELECT COUNT(*) FROM {invoice_invoices}";
@@ -536,46 +539,46 @@
   $rows = array();
   $result = pager_query($query, 15, 0, $count_query);
   while ($row = db_fetch_object($result)) {
-  
-    // Set locale so money has the right format for the preferred culture
-    if ($locale = _invoice_get_variable($row->template, 'locale')) {
-      setlocale(LC_MONETARY, $locale);
-    }
-    
-    // Get locale settings
-    $a_locales = localeconv();
-    
-    // Set formatted create date
-    $created = format_date($row->created, 'custom', variable_get('invoice_date_format' , ''));
-
-    // If no default invoice date format is set, use the small drupal date format
-    if (empty($created)) {
-      $created = format_date($row->created, 'small');
-    }
-    
-    // Get invoice totals
-    $a_totals = _invoice_get_invoice_totals($row->iid); 
-    
-    // Set pay status
-    $pay_status = $row->pay_status == 'paid' ? _invoice_get_icon('bullet_green', NULL, array('title' => t('Paid'))) : _invoice_get_icon('bullet_yellow', NULL, array('title' => t('Unpaid')));
-    
-    // Check if invoice has pay limit, if yes see if the date exceeded it
-    if ($row->pay_status == 'unpaid' && $row->pay_limit > 0) {
-      if (mktime(0, 0, 0, date('m'), date('d'), date('Y')) > $row->created + (86400 * $row->pay_limit)) {
-         $pay_status = _invoice_get_icon('bullet_red', NULL, array('title' => t('Overtime')));
-      }
-    }
-    
+  
+    // Set locale so money has the right format for the preferred culture
+    if ($locale = _invoice_get_variable($row->template, 'locale')) {
+      setlocale(LC_MONETARY, $locale);
+    }
+    
+    // Get locale settings
+    $a_locales = localeconv();
+    
+    // Set formatted create date
+    $created = format_date($row->created, 'custom', variable_get('invoice_date_format' , ''));
+
+    // If no default invoice date format is set, use the small drupal date format
+    if (empty($created)) {
+      $created = format_date($row->created, 'small');
+    }
+    
+    // Get invoice totals
+    $a_totals = _invoice_get_invoice_totals($row->iid); 
+    
+    // Set pay status
+    $pay_status = $row->pay_status == 'paid' ? _invoice_get_icon('bullet_green', NULL, array('title' => t('Paid'))) : _invoice_get_icon('bullet_yellow', NULL, array('title' => t('Unpaid')));
+    
+    // Check if invoice has pay limit, if yes see if the date exceeded it
+    if ($row->pay_status == 'unpaid' && $row->pay_limit > 0) {
+      if (mktime(0, 0, 0, date('m'), date('d'), date('Y')) > $row->created + (86400 * $row->pay_limit)) {
+         $pay_status = _invoice_get_icon('bullet_red', NULL, array('title' => t('Overtime')));
+      }
+    }
+    
     $rows[] = array(
       'invoices.iid' => l(_invoice_get_formatted_invoice_number($row->iid), 'node/'. $row->nid),
       'customer' => !empty($row->company_name) ? _invoice_get_icon('building') .' '. $row->company_name : _invoice_get_icon('user') .' '. $row->lastname . (!empty($row->firstname) ? ', '. $row->firstname : ''),
-      'extotal' => _invoice_round_and_format_money($a_totals['extotal'], 2),
+      'extotal' => _invoice_round_and_format_money($a_totals['extotal'], 2),
       'inctotal' => _invoice_round_and_format_money($a_totals['inctotal'], 2),
-      'invoices.created' => $created,
+      'invoices.created' => $created,
       'ii.status' => $pay_status,
-      'actions' => _invoice_get_icon('edit', 'node/'. $row->nid .'/edit', array('title' => t('Edit')))
-        . ($row->pay_status != 'paid' ? _invoice_get_icon('delete', 'node/'. $row->nid .'/delete', array('title' => t('Delete'))) : '')
-        . ($row->pay_status != 'paid' ? _invoice_get_icon('accept', 'invoice/set/pay_status/'. $row->iid .'/paid/'. _invoice_getvars_array_to_string($_GET), array('title' => t('Set paid'))) : '')
+      'actions' => _invoice_get_icon('edit', 'node/'. $row->nid .'/edit', array('title' => t('Edit')))
+        . ($row->pay_status != 'paid' ? _invoice_get_icon('delete', 'node/'. $row->nid .'/delete', array('title' => t('Delete'))) : '')
+        . ($row->pay_status != 'paid' ? _invoice_get_icon('accept', 'invoice/set/pay_status/'. $row->iid .'/paid/'. _invoice_getvars_array_to_string($_GET), array('title' => t('Set paid'))) : '')
         . ($row->pay_status == 'paid' ? _invoice_get_icon('coins_delete', 'invoice/set/pay_status/'. $row->iid .'/unpaid/'. _invoice_getvars_array_to_string($_GET), array('title' => t('Set unpaid'))) : ''),
     );
   }
@@ -584,370 +587,454 @@
   $content .= theme('pager');
 
   return $content;
-}
-
-/**
- * Implementation of node_validate()
- */
-function invoice_validate($node, $form) {
-  if ($node->op != t('Delete')) {
-    _invoice_add_css_js();
-    
-    // Count invoice items
-    $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_items} WHERE uid=%d AND invoice_id=%d",
-      $GLOBALS['user']->uid,
-      $node->invoice_number
-    ));
-    
-    // Display an error if there are no invoice items
-    if ($count == 0) {
-      form_set_error('description', t('You have to fill in at least one invoice item!'));
-    }
-    
-    if (empty($node->company_name) && empty($node->lastname)) {
-      form_set_error('company_name', t('Company name and lastname may not both be empty!'));
-    }
-  }
-
-  if ($node->op == t('Save')) {
-    $possible_new_invoice_number = _invoice_get_new_invoice_number(true);
-
-    // If user defined invoice number is higher than the new possible invoice number,
-    // use the defined invoice number as the new invoice number
-    if (intval($node->user_defined_invoice_number) > 0) {
-      if ($node->user_defined_invoice_number <= $possible_new_invoice_number) {
-        form_set_error('user_defined_invoice_number', t('The user defined invoice number is not greater than the latest invoice number "@invoice_number"!', array('@invoice_number' => $possible_new_invoice_number)));
-      }
-    }
-  }
-}
-
-/**
- * Implementation of hook_insert()
- */
-function invoice_insert($node) {
-
-  // Get template ID
-  $tid = db_result(db_query("SELECT tid FROM {invoice_templates} WHERE name='%s'", $node->template));
-  
-  // Create invoice
-  db_query("INSERT INTO {invoice_invoices} (iid,nid,leading_zeros,prefix,description,tid,pay_limit,uid) VALUES (%d,%d,%d,'%s','%s',%d,'%s',%d)",
-    $node->invoice_number,
-    $node->nid,
-    empty($node->invoice_invoice_number_zerofill) ? variable_get('invoice_invoice_number_zerofill', 0) : $node->invoice_invoice_number_zerofill,
-    empty($node->invoice_invoice_number_prefix) ? variable_get('invoice_invoice_number_prefix', NULL) : $node->invoice_invoice_number_prefix,
-    $node->invoice_description,
-    $tid,
-    $node->pay_limit,
-    $GLOBALS['user']->uid
-  );
-      
-  // Create customer
-  db_query("INSERT {invoice_customers} (customer_number,company_name,firstname,lastname,street,building_number,zipcode,city,country,coc_number,vat_number,description,invoice_id)
-    VALUES (%d, '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%d)",
-    $node->customer_number,
-    $node->company_name,
-    $node->firstname,
-    $node->lastname,
-    $node->street,
-    $node->building_number,
-    $node->zipcode,
-    $node->city,
-    $node->country,
-    $node->coc_number,
-    $node->vat_number,
-    $node->customer_description,
-    $node->invoice_number
-  );
-      
-  // Add all temporary invoice items to this invoice
-  db_query("UPDATE {invoice_items} SET invoice_id=%d WHERE uid=%d AND invoice_id=0",
-    $node->invoice_number,
-    $GLOBALS['user']->uid
-  );
-  
-  db_query("UPDATE {node} SET promote=0 WHERE type='invoice' AND nid=%d", $node->nid);
-  
-  unset($_SESSION['invoice_template']);  
-}
-
-/**
- * Implementation of hook_update()
- */
-function invoice_update($node) {
-    
-  // Make sure that this invoice belongs to this user
-  $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_invoices} WHERE iid=%d AND uid=%d",
-    $node->invoice_number,
-    $GLOBALS['user']->uid
-  ));
-      
-  if ($count > 0) {       
-    // Get template ID
-    $tid = db_result(db_query("SELECT tid FROM {invoice_templates} WHERE name='%s'", $node->template));
-    
-    // Update invoice
-    db_query("UPDATE {invoice_invoices} SET leading_zeros=%d, prefix='%s', description='%s', tid='%s', pay_limit=%d WHERE iid=%d AND uid=%d",
-      $node->invoice_invoice_number_zerofill,
-      $node->invoice_invoice_number_prefix,
-      $node->invoice_description,
-      $tid,
-      $node->pay_limit,
-      $node->invoice_number,
-      $GLOBALS['user']->uid
-    );
-        
-    // Update customers
-    db_query("UPDATE {invoice_customers} SET customer_number=%d, company_name='%s', firstname='%s', lastname='%s', street='%s', building_number='%s',
-      zipcode='%s', city='%s', country='%s', coc_number='%s', vat_number='%s', description='%s'  
-      WHERE invoice_id=%d",
-      $node->customer_number,
-      $node->company_name,
-      $node->firstname,
-      $node->lastname,
-      $node->street,
-      $node->building_number,
-      $node->zipcode,
-      $node->city,
-      $node->country,
-      $node->coc_number,
-      $node->vat_number,
-      $node->description,
-      $node->invoice_number         
-    );
-        
-    // It's not needed to update invoice items because they are directly updated by every AJAX call
-  }
-  else {
-    drupal_set_message(t('You are not the owner of this invoice!'), 'error');
-  }
-  
-  db_query("UPDATE {node} SET promote=0 WHERE type='invoice' AND nid=%d", $node->nid);
-  
-  unset($_SESSION['invoice_template']);
-}
-
-/**
- * Implemenation of hook_delete()
- */
-function invoice_delete(&$node) {
-  $invoice_number = db_result(db_query("SELECT iid FROM {invoice_invoices} WHERE nid=%d", $node->nid));
-  db_query("DELETE FROM {invoice_invoices} WHERE iid=%d", $invoice_number);
-  db_query("DELETE FROM {invoice_customers} WHERE invoice_id=%d", $invoice_number);
-  db_query("DELETE FROM {invoice_items} WHERE invoice_id=%d", $invoice_number);
-  unset($_SESSION['invoice_template']);
-}
-
-/**
- * Implementation of hook_view()
- */
-function invoice_view($node, $teaser = FALSE, $page = FALSE) {
-  $node->content['body'] = array(
-    '#value' => '<div class="view">'. theme('invoice_body', $node, 'view') .'</div>',    
-    '#weight' => 0,
-  );
-
-  $links = '<div class="invoice-links">';
-  $links .= _invoice_get_icon('pdf', 'invoice/pdf/'. $node->invoice['invoice_number'], array('width' => '30', 'height' => '30'), 'jpg');
-  $links .= _invoice_get_icon('print', 'invoice/print/'. $node->invoice['invoice_number'], array('width' => '30', 'height' => '30'), 'jpg');
-  $links .= '</div>';
-  
-  $node->content['invoice_links'] = array(
-    '#value' => $links,
-    '#weight' => 1,
-  );
-  
-  return $node;
-}
-
-/**
- * List of installed locales
- */
-function invoice_installed_locales() {
-  $locales = _invoice_get_installed_system_locales();
-  
-  if (count($locales) > 0 && !empty($locales[0])) {
-    $content = '<ul>';
-    foreach ($locales as $locale) {
-      $content .= '<li>'. $locale .'</li>';
-    }
-    $content .= '</ul>';
-  }
-  else {
-    $content = 'No locales found. But maybe the "locale -a" command is not supported on your server.';
-  }
-  
-  return $content;
-}
-
-/**
- * Set the status of an invoice to paid
- */
-function invoice_set_pay_status($invoice_number, $status) {
-
-  if ($status != 'paid' && $status != 'unpaid') {
-    drupal_set_message(t('Invalid invoice pay status'), 'error');
-  }
-  else {
-    db_query("UPDATE {invoice_invoices} SET pay_status='%s' WHERE iid=%d", $status, $invoice_number);
-    drupal_set_message('Succesfully changed pay status of invoice '. check_plain($invoice_number) .' to "paid"');
-  }
-
-  $exp = explode('?', $_GET['q']);
-  $query_string = '?q=&'. $exp[1];
-  
-  $a_query_vars = _invoice_getvars_string_to_array($query_string);
-
-  drupal_goto('invoices', $a_query_vars);
-}
-
-/**
- * Display the invoice in HTML print format
- */
-function invoice_view_print($invoice_number) {
-  echo _invoice_get_html($invoice_number);
-}
-
-/**
- * Display the invoice in PDF format
- */
-function invoice_view_pdf($invoice_number) {
-  // include the dompdf library
-  _invoice_dompdf_include_lib();
-  $html = _invoice_get_html($invoice_number, 'pdf');
-  $dompdf = new DOMPDF();
-  $dompdf->load_html($html);
-  $dompdf->render();
-  $dompdf->stream("invoice-". $invoice_number .".pdf", array('Attachment' => 1));
-  die();
-}
-
-/**
- * Theme function for displaying the invoice
- */
-function theme_invoice_body($node, $type=NULL) {
-
-  $content = '<div class="invoice-wrapper">';
-  
-  require_once dirname(__FILE__) .'/templates/'. $node->invoice['template'] .'.inc';
-  drupal_add_css(drupal_get_path('module', 'invoice') .'/templates/'. $node->invoice['template'] .'.css', 'module');
-
-  $content_function = '_invoice_'. $node->invoice['template'] .'_get_template_output';
-  $content .= $content_function($node, $type);  
-  
-  $content .= '</div>';
-  
-  return $content;
-}
-
-/**
- * Add extra markup info to a markup form field
- *
- * @param string $s_field_name
- * @param mixed $value
- * @param string $s_title
- */
-function theme_invoice_markup($s_field_name, $value, $s_title) {
-  $markup_before = '<div id="edit-'. $s_field_name .'-wrapper" class="form-item">
-    <label for="edit-'. $s_field_name .'">'. $s_title .':</label><div>';
-  $markup_after = '</div></div>';
-  
-  return $markup_before . $value . $markup_after; 
-}
-
-
-/**
- * An override for the table_theme() function
- *
- * Added the possibility to disable the sticky header
- * 
- * @param unknown_type $header
- * @param unknown_type $rows
- * @param unknown_type $attributes
- * @param unknown_type $caption
- * @return unknown
- */
-function theme_invoice_table($header, $rows, $attributes = array(), $caption = NULL) {
-
-  // Add sticky headers, if applicable.
-  if (count($header) && (bool) $attributes['disable_sticky_header'] != TRUE) {
-    drupal_add_js('misc/tableheader.js');
-    // Add 'sticky-enabled' class to the table to identify it for JS.
-    // This is needed to target tables constructed by this function.
-    $attributes['class'] = empty($attributes['class']) ? 'sticky-enabled' : ($attributes['class'] .' sticky-enabled');
-  }
-  else {
-    unset($attributes['disable_sticky_header']);
-  }
-
-  $output = '<table'. drupal_attributes($attributes) .">\n";
-
-  if (isset($caption)) {
-    $output .= '<caption>'. $caption ."</caption>\n";
-  }
-
-  // Format the table header:
-  if (count($header)) {
-    $ts = tablesort_init($header);
-    // HTML requires that the thead tag has tr tags in it follwed by tbody
-    // tags. Using ternary operator to check and see if we have any rows.
-    $output .= (count($rows) ? ' <thead><tr>' : ' <tr>');
-    foreach ($header as $cell) {
-      $cell = tablesort_header($cell, $header, $ts);
-      $output .= _theme_table_cell($cell, TRUE);
-    }
-    // Using ternary operator to close the tags based on whether or not there are rows
-    $output .= (count($rows) ? " </tr></thead>\n" : "</tr>\n");
-  }
-  else {
-    $ts = array();
-  }
-
-  // Format the table rows:
-  if (count($rows)) {
-    $output .= "<tbody>\n";
-    $flip = array('even' => 'odd', 'odd' => 'even');
-    $class = 'even';
-    foreach ($rows as $number => $row) {
-      $attributes = array();
-
-      // Check if we're dealing with a simple or complex row
-      if (isset($row['data'])) {
-        foreach ($row as $key => $value) {
-          if ($key == 'data') {
-            $cells = $value;
-          }
-          else {
-            $attributes[$key] = $value;
-          }
-        }
-      }
-      else {
-        $cells = $row;
-      }
-      if (count($cells)) {
-        // Add odd/even class
-        $class = $flip[$class];
-        if (isset($attributes['class'])) {
-          $attributes['class'] .= ' '. $class;
-        }
-        else {
-          $attributes['class'] = $class;
-        }
-
-        // Build row
-        $output .= ' <tr'. drupal_attributes($attributes) .'>';
-        $i = 0;
-        foreach ($cells as $cell) {
-          $cell = tablesort_cell($cell, $header, $ts, $i++);
-          $output .= _theme_table_cell($cell);
-        }
-        $output .= " </tr>\n";
-      }
-    }
-    $output .= "</tbody>\n";
-  }
-
-  $output .= "</table>\n";
-  return $output;
-}
+}
+
+/**
+ * Implementation of node_validate()
+ */
+function invoice_validate($node, $form) {
+  if ($node->op != t('Delete')) {
+    _invoice_add_css_js();
+    
+    // Count invoice items
+    $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_items} WHERE uid=%d AND invoice_id=%d",
+      $GLOBALS['user']->uid,
+      $node->invoice_number
+    ));
+    
+    // Display an error if there are no invoice items
+    if ($count == 0) {
+      form_set_error('description', t('You have to fill in at least one invoice item!'));
+    }
+    
+    if (empty($node->company_name) && empty($node->lastname)) {
+      form_set_error('company_name', t('Company name and lastname may not both be empty!'));
+    }
+	$access_users = explode(',', $node->invoice_access_users);
+    foreach($access_users as $access_user) {
+      $uid = db_result(db_query('SELECT uid FROM {users} WHERE name = "%s"', trim($access_user)));
+      if(!$uid) {
+        form_set_error('invoice_access_users', t('No user exists with the username: @user', array('@user' => trim($access_user))));
+      }
+    }
+  }
+
+  if ($node->op == t('Save')) {
+    $possible_new_invoice_number = _invoice_get_new_invoice_number(true);
+
+    // If user defined invoice number is higher than the new possible invoice number,
+    // use the defined invoice number as the new invoice number
+    if (intval($node->user_defined_invoice_number) > 0) {
+      if ($node->user_defined_invoice_number <= $possible_new_invoice_number) {
+        form_set_error('user_defined_invoice_number', t('The user defined invoice number is not greater than the latest invoice number "@invoice_number"!', array('@invoice_number' => $possible_new_invoice_number)));
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_insert()
+ */
+function invoice_insert($node) {
+
+  // Get template ID
+  $tid = db_result(db_query("SELECT tid FROM {invoice_templates} WHERE name='%s'", $node->template));
+  
+  // Create invoice
+  db_query("INSERT INTO {invoice_invoices} (iid,nid,leading_zeros,prefix,description,tid,pay_limit,uid) VALUES (%d,%d,%d,'%s','%s',%d,'%s',%d)",
+    $node->invoice_number,
+    $node->nid,
+    empty($node->invoice_invoice_number_zerofill) ? variable_get('invoice_invoice_number_zerofill', 0) : $node->invoice_invoice_number_zerofill,
+    empty($node->invoice_invoice_number_prefix) ? variable_get('invoice_invoice_number_prefix', NULL) : $node->invoice_invoice_number_prefix,
+    $node->invoice_description,
+    $tid,
+    $node->pay_limit,
+    $GLOBALS['user']->uid
+  );
+      
+  // Create customer
+  db_query("INSERT {invoice_customers} (customer_number,company_name,firstname,lastname,street,building_number,zipcode,city,country,coc_number,vat_number,description,invoice_id)
+    VALUES (%d, '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%d)",
+    $node->customer_number,
+    $node->company_name,
+    $node->firstname,
+    $node->lastname,
+    $node->street,
+    $node->building_number,
+    $node->zipcode,
+    $node->city,
+    $node->country,
+    $node->coc_number,
+    $node->vat_number,
+    $node->customer_description,
+    $node->invoice_number
+  );
+      
+  // Add all temporary invoice items to this invoice
+  db_query("UPDATE {invoice_items} SET invoice_id=%d WHERE uid=%d AND invoice_id=0",
+    $node->invoice_number,
+    $GLOBALS['user']->uid
+  );
+  
+  db_query("UPDATE {node} SET promote=0 WHERE type='invoice' AND nid=%d", $node->nid);
+  
+  $access_users = explode(',', $node->invoice_access_users);
+  $query = 'INSERT INTO {invoice_access_users} (uid, nid) VALUES ';
+  $query2 = '';
+  $arguments = array();
+  $uids = array();
+  foreach($access_users as $au) {
+	$uid = db_result(db_query('SELECT uid FROM {users} WHERE name = "%s"', $au));
+    if(!in_array($uid, $uids)) {
+      if(strlen($query2)) {
+        $query2 .= ', ';
+      }
+      $query2 .= '(%d, ' . $node->nid . ')';
+      $arguments[] = $uid;
+    }
+  }
+
+  if(strlen($query2)) {
+    db_query($query . $query2, $arguments);
+  }
+  
+  unset($_SESSION['invoice_template']);  
+}
+
+/**
+ * Implementation of hook_update()
+ */
+function invoice_update($node) {
+    
+  // Make sure that this invoice belongs to this user
+  $count = db_result(db_query("SELECT COUNT(*) FROM {invoice_invoices} WHERE iid=%d AND uid=%d",
+    $node->invoice_number,
+    $GLOBALS['user']->uid
+  ));
+      
+  if ($count > 0) {       
+    // Get template ID
+    $tid = db_result(db_query("SELECT tid FROM {invoice_templates} WHERE name='%s'", $node->template));
+    
+    // Update invoice
+    db_query("UPDATE {invoice_invoices} SET leading_zeros=%d, prefix='%s', description='%s', tid='%s', pay_limit=%d WHERE iid=%d AND uid=%d",
+      $node->invoice_invoice_number_zerofill,
+      $node->invoice_invoice_number_prefix,
+      $node->invoice_description,
+      $tid,
+      $node->pay_limit,
+      $node->invoice_number,
+      $GLOBALS['user']->uid
+    );
+        
+    // Update customers
+    db_query("UPDATE {invoice_customers} SET customer_number=%d, company_name='%s', firstname='%s', lastname='%s', street='%s', building_number='%s',
+      zipcode='%s', city='%s', country='%s', coc_number='%s', vat_number='%s', description='%s'  
+      WHERE invoice_id=%d",
+      $node->customer_number,
+      $node->company_name,
+      $node->firstname,
+      $node->lastname,
+      $node->street,
+      $node->building_number,
+      $node->zipcode,
+      $node->city,
+      $node->country,
+      $node->coc_number,
+      $node->vat_number,
+      $node->description,
+      $node->invoice_number         
+    );
+        
+    // It's not needed to update invoice items because they are directly updated by every AJAX call
+  }
+  else {
+    drupal_set_message(t('You are not the owner of this invoice!'), 'error');
+  }
+  
+  db_query('DELETE FROM {invoice_access_users} WHERE nid = %d', $node->nid);
+  $access_users = explode(',', $node->invoice_access_users);
+  $query = 'INSERT INTO {invoice_access_users} (uid, nid) VALUES ';
+  $query2 = '';
+  $arguments = array();
+  $uids = array();
+  foreach($access_users as $au) {
+	$uid = db_result(db_query('SELECT uid FROM {users} WHERE name = "%s"', $au));
+    if(!in_array($uid, $uids)) {
+      if(strlen($query2)) {
+        $query2 .= ', ';
+      }
+      $query2 .= '(%d, ' . $node->nid . ')';
+      $arguments[] = $uid;
+    }
+  }
+  
+  db_query("UPDATE {node} SET promote=0 WHERE type='invoice' AND nid=%d", $node->nid);
+  
+  unset($_SESSION['invoice_template']);
+}
+
+/**
+ * Implemenation of hook_delete()
+ */
+function invoice_delete(&$node) {
+  $invoice_number = db_result(db_query("SELECT iid FROM {invoice_invoices} WHERE nid=%d", $node->nid));
+  db_query("DELETE FROM {invoice_invoices} WHERE iid=%d", $invoice_number);
+  db_query("DELETE FROM {invoice_customers} WHERE invoice_id=%d", $invoice_number);
+  db_query("DELETE FROM {invoice_items} WHERE invoice_id=%d", $invoice_number);
+  db_query('DELETE FROM {invoice_access_users} WHERE nid = %d', $node->nid);
+  unset($_SESSION['invoice_template']);
+}
+
+function invoice_node_access_records($node) {
+  $grants = array();
+  if($node->type == 'invoice') {
+    $grants[] = array(
+      'realm' => 'access_invoice',
+      'gid' => $node->nid,
+      'grant_view' => TRUE,
+      'grant_update' => FALSE,
+      'grant_delete' => FALSE,
+      'priority' => 0,
+    );
+  }
+  return $grants;
+}
+
+function invoice_node_grants($account, $op) {
+  $grants = array();
+  $db_invoice_access_nids = db_query('SELECT nid FROM {invoice_access_users} WHERE uid = %d', $account->uid);
+  while($access_nid = db_fetch_array($db_invoice_access_nids))
+  {
+    $grants['access_invoice'][] = $access_nid['nid'];
+  }
+  return $grants;
+}
+
+/**
+ * Implementation of hook_view()
+ */
+function invoice_view($node, $teaser = FALSE, $page = FALSE) {
+  $node->content['body'] = array(
+    '#value' => '<div class="view">'. theme('invoice_body', $node, 'view') .'</div>',    
+    '#weight' => 0,
+  );
+
+  $links = '<div class="invoice-links">';
+  $links .= _invoice_get_icon('pdf', 'invoice/pdf/'. $node->invoice['invoice_number'], array('width' => '30', 'height' => '30'), 'jpg');
+  $links .= _invoice_get_icon('print', 'invoice/print/'. $node->invoice['invoice_number'], array('width' => '30', 'height' => '30'), 'jpg');
+  $links .= '</div>';
+  
+  $node->content['invoice_links'] = array(
+    '#value' => $links,
+    '#weight' => 1,
+  );
+  
+  return $node;
+}
+
+/**
+ * List of installed locales
+ */
+function invoice_installed_locales() {
+  $locales = _invoice_get_installed_system_locales();
+  
+  if (count($locales) > 0 && !empty($locales[0])) {
+    $content = '<ul>';
+    foreach ($locales as $locale) {
+      $content .= '<li>'. $locale .'</li>';
+    }
+    $content .= '</ul>';
+  }
+  else {
+    $content = 'No locales found. But maybe the "locale -a" command is not supported on your server.';
+  }
+  
+  return $content;
+}
+
+/**
+ * Set the status of an invoice to paid
+ */
+function invoice_set_pay_status($invoice_number, $status) {
+
+  if ($status != 'paid' && $status != 'unpaid') {
+    drupal_set_message(t('Invalid invoice pay status'), 'error');
+  }
+  else {
+    db_query("UPDATE {invoice_invoices} SET pay_status='%s' WHERE iid=%d", $status, $invoice_number);
+    drupal_set_message('Succesfully changed pay status of invoice '. check_plain($invoice_number) .' to "paid"');
+  }
+
+  $exp = explode('?', $_GET['q']);
+  $query_string = '?q=&'. $exp[1];
+  
+  $a_query_vars = _invoice_getvars_string_to_array($query_string);
+
+  drupal_goto('invoices', $a_query_vars);
+}
+
+/**
+ * Display the invoice in HTML print format
+ */
+function invoice_view_print($invoice_number) {
+  echo _invoice_get_html($invoice_number);
+}
+
+/**
+ * Display the invoice in PDF format
+ */
+function invoice_view_pdf($invoice_number) {
+  // include the dompdf library
+  _invoice_dompdf_include_lib();
+  $html = _invoice_get_html($invoice_number, 'pdf');
+  $dompdf = new DOMPDF();
+  $dompdf->load_html($html);
+  $dompdf->render();
+  $dompdf->stream("invoice-". $invoice_number .".pdf", array('Attachment' => 1));
+  die();
+}
+
+/**
+ * Theme function for displaying the invoice
+ */
+function theme_invoice_body($node, $type=NULL) {
+
+  $content = '<div class="invoice-wrapper">';
+  
+  require_once dirname(__FILE__) .'/templates/'. $node->invoice['template'] .'.inc';
+  drupal_add_css(drupal_get_path('module', 'invoice') .'/templates/'. $node->invoice['template'] .'.css', 'module');
+
+  $content_function = '_invoice_'. $node->invoice['template'] .'_get_template_output';
+  $content .= $content_function($node, $type);  
+  
+  $content .= '</div>';
+  
+  return $content;
+}
+
+/**
+ * Add extra markup info to a markup form field
+ *
+ * @param string $s_field_name
+ * @param mixed $value
+ * @param string $s_title
+ */
+function theme_invoice_markup($s_field_name, $value, $s_title) {
+  $markup_before = '<div id="edit-'. $s_field_name .'-wrapper" class="form-item">
+    <label for="edit-'. $s_field_name .'">'. $s_title .':</label><div>';
+  $markup_after = '</div></div>';
+  
+  return $markup_before . $value . $markup_after; 
+}
+
+
+/**
+ * An override for the table_theme() function
+ *
+ * Added the possibility to disable the sticky header
+ * 
+ * @param unknown_type $header
+ * @param unknown_type $rows
+ * @param unknown_type $attributes
+ * @param unknown_type $caption
+ * @return unknown
+ */
+function theme_invoice_table($header, $rows, $attributes = array(), $caption = NULL) {
+
+  // Add sticky headers, if applicable.
+  if (count($header) && (bool) $attributes['disable_sticky_header'] != TRUE) {
+    drupal_add_js('misc/tableheader.js');
+    // Add 'sticky-enabled' class to the table to identify it for JS.
+    // This is needed to target tables constructed by this function.
+    $attributes['class'] = empty($attributes['class']) ? 'sticky-enabled' : ($attributes['class'] .' sticky-enabled');
+  }
+  else {
+    unset($attributes['disable_sticky_header']);
+  }
+
+  $output = '<table'. drupal_attributes($attributes) .">\n";
+
+  if (isset($caption)) {
+    $output .= '<caption>'. $caption ."</caption>\n";
+  }
+
+  // Format the table header:
+  if (count($header)) {
+    $ts = tablesort_init($header);
+    // HTML requires that the thead tag has tr tags in it follwed by tbody
+    // tags. Using ternary operator to check and see if we have any rows.
+    $output .= (count($rows) ? ' <thead><tr>' : ' <tr>');
+    foreach ($header as $cell) {
+      $cell = tablesort_header($cell, $header, $ts);
+      $output .= _theme_table_cell($cell, TRUE);
+    }
+    // Using ternary operator to close the tags based on whether or not there are rows
+    $output .= (count($rows) ? " </tr></thead>\n" : "</tr>\n");
+  }
+  else {
+    $ts = array();
+  }
+
+  // Format the table rows:
+  if (count($rows)) {
+    $output .= "<tbody>\n";
+    $flip = array('even' => 'odd', 'odd' => 'even');
+    $class = 'even';
+    foreach ($rows as $number => $row) {
+      $attributes = array();
+
+      // Check if we're dealing with a simple or complex row
+      if (isset($row['data'])) {
+        foreach ($row as $key => $value) {
+          if ($key == 'data') {
+            $cells = $value;
+          }
+          else {
+            $attributes[$key] = $value;
+          }
+        }
+      }
+      else {
+        $cells = $row;
+      }
+      if (count($cells)) {
+        // Add odd/even class
+        $class = $flip[$class];
+        if (isset($attributes['class'])) {
+          $attributes['class'] .= ' '. $class;
+        }
+        else {
+          $attributes['class'] = $class;
+        }
+
+        // Build row
+        $output .= ' <tr'. drupal_attributes($attributes) .'>';
+        $i = 0;
+        foreach ($cells as $cell) {
+          $cell = tablesort_cell($cell, $header, $ts, $i++);
+          $output .= _theme_table_cell($cell);
+        }
+        $output .= " </tr>\n";
+      }
+    }
+    $output .= "</tbody>\n";
+  }
+
+  $output .= "</table>\n";
+  return $output;
+}
+
+function invoice_autocomplete_users_multiple($string) {
+  $parts = explode(',', $string);
+  $search = array_pop($parts);
+  $current_string = (count($parts)) ? implode(',', $parts) . ',': '';
+
+  $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", trim($search), 0, 10);
+
+  while ($user = db_fetch_object($result)) {
+    $matches[$current_string . $user->name] = check_plain($user->name);
+  }
+  print drupal_to_js($matches);
+  exit();
+}
Index: invoice_form.inc
===================================================================
--- invoice_form.inc	(revision 1)
+++ invoice_form.inc	(working copy)
@@ -1,784 +1,802 @@
-<?php
-// $Id: invoice_form.inc,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
-
-/**
- * @file
- * Invoice module
- *
- * This module was developed by Platina Designs, http://www.platinadesigns.nl
- *
- * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
- */
-
-/**
- * Implementatin of node_form()
- */
-function invoice_form(&$form_state, $node) {
-  _invoice_add_css_js();
-
-  //drupal_add_tabledrag('invoice-items-table', 'order', 'sibling', 'invoice-item', $subgroup = NULL, $source = NULL, $hidden = TRUE, $limit = 0);
-  
-  // If an invoice number is available we are in editing mode
-  if (!empty($form_state->invoice['invoice_number'])) {
-    $mode = 'edit';
-  }
-  else {
-    $mode = 'create';
-  }
-
-  $form = array();
-  $form['invoice_template'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Invoice template'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#weight' => 1,    
-  );
-
-  // Get template names
-  $a_templates = _invoice_get_templates();
-
-  // Build array for selecting the default template
-  $a_template_options = array();
-  foreach ($a_templates as $s_template) {
-    $a_template_options[$s_template] = ucfirst($s_template);
-  }
-
-  $active_template = empty($form_state->invoice['template']) ? _invoice_get_chosen_template() : $form_state->invoice['template'];
-
-  $form['invoice_template']['template'] = array(
-    '#type' => 'select',
-    '#title' => '',
-    '#options' => $a_template_options,
-    '#default_value' => $active_template,
-    '#attributes' => empty($form_state->invoice['template']) ? array('onchange' => 'invoice_set_template(this.value)') : array(),
-    '#description' => t("When editing this invoice, you'll have to save first before you can see template changes."),
-  );
-
-  if (empty($form_state->invoice['template'])) {
-    $_SESSION['invoice_template'] = _invoice_get_chosen_template();
-  }
-
-  $form['customer'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Customer details'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#description' => t('You either have to fill in Company name or Lastname. Firstname is optional and is only saved if a Lastname is filled in.'),
-    '#weight' => 2,
-  );
-  $form['customer']['search'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Search customer'),
-    '#maxlength' => 60,
-    '#autocomplete_path' => 'invoice/search/customer',
-    '#default_value' => !empty($form_state->customer['company_name']) ? $form_state->customer['company_name'] : $form_state->customer['lastname'] . (!empty($form_state->customer['firstname']) ? ', '. $form_state->customer['firstname'] : ''),
-  );
-  $form['customer']['company_name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Company name'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['company_name'],
-  );
-  $form['customer']['firstname'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Firstname'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['firstname'],
-  );
-  $form['customer']['lastname'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Lastname'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['lastname'],
-  );
-
-  $invoice_items_table_header = array(
-  t('Description'),
-  t('VAT'),
-  t('Count'),
-  t('Unitcost (ex. VAT)'),
-  t('Unitcost (inc. VAT)'),
-  t('Subtotal (ex. VAT)'),
-  t('Subtotal (inc. VAT)'),
-    '',
-  );
-
-  $form['invoice_items'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Invoice items'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#weight' => 4,
-  );
-
-  // Set locale so money has the right format for the preferred culture
-  if (intval($form_state->invoice['invoice_number']) == 0) {
-    if ($locale = _invoice_get_variable(_invoice_get_chosen_template(), 'locale')) {
-      setlocale(LC_MONETARY, $locale);
-    }
-  }
-  elseif ($locale = _invoice_get_variable($active_template, 'locale')) {
-    setlocale(LC_MONETARY, $locale);
-  }
-
-  // Get invoice items
-  $a_items = _invoice_get_invoice_items($form_state->invoice['invoice_number']);
-  $count = $a_items['count'];
-  $invoice_items_table_rows = $a_items['rows'];
-
-  // If now rows are found add an empty row
-  if ($count == 0) {
-    $invoice_items_table_rows = array(
-      array(
-        'data' => array(array('data' => t('Empty') .'...', 'colspan' => '7')),
-        'class' => 'invoice-items-empty'          
-      ),
-    );
-  }
-  else {
-    // Count the added items
-    $a_totals = _invoice_get_invoice_totals($form_state->invoice['invoice_number'], $GLOBALS['user']->uid);
-    $total->extotal = $a_totals['extotal'];
-    $total->inctotal = $a_totals['inctotal'];
-  }
-
-  $invoice_items_table = theme('invoice_table', $invoice_items_table_header, $invoice_items_table_rows, array('id' => 'invoice-items-table', 'disable_sticky_header' => TRUE));
-  $invoice_items_table_footer = '<tfoot><tr><td colspan="5"></td><td class="extotal">'. _invoice_round_and_format_money($total->extotal, 2) .'</td><td class="inctotal">'. _invoice_round_and_format_money($total->inctotal, 2) .'</td><td></td></tr></tfoot>';
-  $invoice_items_table = str_replace('</table>', $invoice_items_table_footer .'</table>', $invoice_items_table);
-
-  $form['invoice_items']['items'] = array(
-    '#value' => '<div class="invoice-items">'. $invoice_items_table .'</div>',    
-  );
-  $form['invoice_items']['iid'] = array(
-    '#type' => 'hidden',
-    '#title' => t('Invoice item id'),
-    '#required' => FALSE,
-  );
-  $form['invoice_items']['description'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#required' => FALSE,
-    '#rows' => 1,
-  );
-  $form['invoice_items']['quantity'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Quantity'),
-    '#required' => FALSE,
-    '#size' => 5,
-  );
-  $form['invoice_items']['price_without_vat'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Price without VAT'),
-    '#required' => FALSE,
-    '#description' => t("If you don't fill in this field, you'll have to fill in \"Price with VAT\""),
-  );
-  $form['invoice_items']['price_with_vat'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Price with VAT'),
-    '#required' => FALSE,
-    '#description' => t("If you don't fill in this field, you'll have to fill in \"Price without VAT\""),
-  );
-  $form['invoice_items']['vat'] = array(
-    '#type' => 'textfield',
-    '#title' => t('VAT percentage'),
-    '#required' => TRUE,
-    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
-    '#default_value' => _invoice_get_variable($active_template, 'vat'),
-  );
-  $form['invoice_items']['save_item'] = array(
-    '#value' => '<input type="button" id="button-save-item" name="button_save_item" value="'. t('Add item') .'" onclick="invoice_save_item()" />',    
-  );
-
-  $form['customer_optional'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Customer details') .' ('. t('optional') .')',
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#weight' => 3, 
-  );
-  $form['customer_optional']['street'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Street'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['street'],
-  );
-  $form['customer_optional']['building_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Building number'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['building_number'],
-  );
-  $form['customer_optional']['zipcode'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Zipcode'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['zipcode'],
-  );
-  $form['customer_optional']['city'] = array(
-    '#type' => 'textfield',
-    '#title' => t('City'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['city'],
-  );
-  $form['customer_optional']['country'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Country'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['country'],
-  );
-  $form['customer_optional']['coc_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Chamber of Commerce number'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['coc_number'],
-  );
-  $form['customer_optional']['vat_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('VAT number'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['vat_number'],
-  );
-  $form['customer_optional']['customer_description'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->customer['description'],
-  );
-
-  $form['invoice_details'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Invoice details') .' ('. t('optional') .')',
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#weight' => 5,
-  );
-
-  // Only display this form field when creating a node
-  if (empty($form_state->invoice['invoice_number'])) {
-    $form['invoice_details']['user_defined_invoice_number'] = array(
-      '#type' => 'textfield',
-      '#title' => t('User defined invoice number'),
-      '#required' => FALSE,
-      '#default_value' => '',
-      '#attributes' => array('style' => 'width:200px;'), // size attribute didn't work here for some strange reason
-      '#description' => t('You can define an invoice number here. The number has to be higher than the latest invoice number though. It also has to be numeric.'),
-    );
-  }
-  $form['invoice_details']['invoice_number'] = array(
-    '#type' => 'hidden',
-    '#title' => t('Invoice number'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->invoice['invoice_number'],
-  );
-  $form['invoice_details']['pay_limit'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Pay limit'),
-    '#required' => FALSE,
-    '#default_value' => empty($form_state->invoice['pay_limit']) ? _invoice_get_variable($active_template, 'pay_limit') : $form_state->invoice['pay_limit'],
-    '#description' => t('Pay limit in days'),
-    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
-  );
-  $form['invoice_details']['invoice_description'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#required' => FALSE,
-    '#default_value' => $form_state->invoice['description'],
-  );
-  $form['invoice_details']['invoice_invoice_number_zerofill'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Invoice number zerofill'),
-    '#required' => FALSE,
-    '#default_value' => empty($form_state->invoice['invoice_number_zerofill']) && $mode == 'create' ? variable_get('invoice_invoice_number_zerofill', 0) : $form_state->invoice['invoice_number_zerofill'],
-    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
-    '#description' => t('If you want an invoice number to be displayed as "0001" fill in 4. If you just want to display invoice number "1" leave/set empty.'),
-  );
-  $form['invoice_details']['invoice_invoice_number_prefix'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Invoice number prefix'),
-    '#required' => FALSE,
-    '#default_value' => empty($form_state->invoice['invoice_number_prefix']) && $mode == 'create' ? variable_get('invoice_invoice_number_prefix', '') : $form_state->invoice['invoice_number_prefix'],
-    '#attributes' => array('style' => 'width:150px;'), // size attribute didn't work here for some strange reason
-    '#description' => t('If you want an invoice number to be displayed as "@year0001" fill in "%Y". Fillin 4 in the zerofill field above for extra zero values.', array('@year' => date('Y')))
-  .' '. t('If a new year is reached the numbering will still continue sequentially, so if the year ended with "@year0578", the next year will start with "@next_year0579"', array('@year' => date('Y'), '@next_year' => date('Y') + 1))
-  .' '. t('All !date values may be entered here with a "%" sign before it or every other text you like.', array('!date' => l('date', 'http://www.php.net/date', array('absolute' => TRUE)))),
-  );
-
-  return $form;
-}
-
-/**
- * Invoice settings form
- */
-function invoice_settings_form() {
-
-  // Get template names
-  $a_templates = _invoice_get_templates();
-
-  $form['general'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('General settings'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,    
-  );
-  $form['general']['locale'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Locale'),
-    '#required' => TRUE,
-    '#default_value' => variable_get('invoice_locale', ''),
-    '#description' => t('Category/locale names can be found in !rfc1766 and !iso639. Systems can have different naming schemes for locales.',
-  array(
-       '!rfc1766' => l('» RFC 1766', 'http://www.faqs.org/rfcs/rfc1766', array('absolute' => TRUE)),
-       '!iso639' => l('» ISO 639', 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm', array('absolute' => TRUE)),
-  )
-  ) .' '. t('On linux you can check the available locales on the server with the command "locale -a" or click below to see the same list.')
-  .' '. t('If your system/server is ubuntu (debian like) you can install more languages with the aptitude or synaptic package manager. Search for -language-pack-*-base.')
-  .' '. t('If you install for example -language-pack-en-base you get over 10+ locales extra, like en_US, en_GB, en_AU, en_CA etc.')
-  .' '. t('For more information see !link.', array('!link' => l('http://www.php.net/setlocale', 'http://www.php.net/setlocale', array('absolute' => TRUE))))
-  .' '. l('Click here to see an overview of installed locales on your system.', 'invoice/installed_locales'),
-    '#size' => 8,
-  );
-  $form['general']['date_format'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Date format'),
-    '#required' => TRUE,
-    '#default_value' => variable_get('invoice_date_format', ''),
-    '#description' => t('The date on the invoice will look like: @date_format', array('@date_format' => date(variable_get('invoice_date_format', '')))),
-    '#size' => 20,
-  );
-  $form['general']['vat'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Default VAT precentage'),
-    '#required' => TRUE,
-    '#default_value' => variable_get('invoice_vat', ''),
-    '#size' => 3,
-  );
-  $form['general']['pay_limit'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Pay limit'),
-    '#required' => TRUE,
-    '#default_value' => variable_get('invoice_pay_limit', ''),
-    '#description' => t('Pay limit in days'),
-    '#size' => 3,
-  );
-  $form['general']['invoice_number_zerofill'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Invoice number zerofill'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_invoice_number_zerofill', ''),
-    '#description' => t('If you want an invoice number to be displayed as "0001" fill in 4. If you just want to display invoice number "1" leave/set empty.'),
-    '#size' => 3,
-  );
-  $form['general']['invoice_number_prefix'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Invoice number prefix'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_invoice_number_prefix', ''),
-    '#description' => t('If you want an invoice number to be displayed as "@year0001" fill in "%Y". Fillin 4 in the zerofill field above for extra zero values.', array('@year' => date('Y')))
-  .' '. t('If a new year is reached the numbering will still continue sequentially, so if the year ended with "@year0578", the next year will start with "@next_year0579"', array('@year' => date('Y'), '@next_year' => date('Y') + 1))
-  .' '. t('All !date values may be entered here with a "%" sign before it or every other text you like.', array('!date' => l('date', 'http://www.php.net/date', array('absolute' => TRUE)))),
-    '#size' => 20,
-  );
-
-  /*------------------------------------------------------*/
-
-  $form['general']['display_column'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Display invoice columns'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['general']['display_column']['display_column_vat'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('VAT'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_display_column_vat', ''),    
-  );
-  $form['general']['display_column']['display_column_exunitcost'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Unitcost (ex)'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_display_column_exunitcost', ''),    
-  );
-  $form['general']['display_column']['display_column_incunitcost'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Unitcost (inc)'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_display_column_incunitcost', ''),    
-  );
-  $form['general']['display_column']['display_column_extotal'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Total (ex)'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_display_column_extotal', ''),    
-  );
-  $form['general']['display_column']['display_column_inctotal'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Total (inc)'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_display_column_inctotal', ''),    
-  );
-
-  /*------------------------------------------------------*/
-
-  $form['general']['supplier'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Supplier details'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['general']['supplier']['supplier_company_name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Company name'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_company_name', ''),    
-  );
-  $form['general']['supplier']['supplier_street'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Street'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_street', ''),    
-  );
-  $form['general']['supplier']['supplier_building_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Building number'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_building_number', ''),    
-  );
-  $form['general']['supplier']['supplier_zipcode'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Zipcode'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_zipcode', ''),    
-  );
-  $form['general']['supplier']['supplier_city'] = array(
-    '#type' => 'textfield',
-    '#title' => t('City'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_city', ''),    
-  );
-  $form['general']['supplier']['supplier_country'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Country'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_country', ''),    
-  );
-  $form['general']['supplier']['supplier_phone'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Phone'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_phone', ''),    
-  );
-  $form['general']['supplier']['supplier_fax'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Fax'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_fax', ''),    
-  );
-  $form['general']['supplier']['supplier_email'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Email'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_email', ''),    
-  );
-  $form['general']['supplier']['supplier_web'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Web address'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_web', ''),    
-  );
-  $form['general']['supplier']['supplier_coc_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('CoC Number'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_coc_number', ''),    
-  );
-  $form['general']['supplier']['supplier_vat_number'] = array(
-    '#type' => 'textfield',
-    '#title' => t('VAT Number'),
-    '#required' => FALSE,
-    '#default_value' => variable_get('invoice_supplier_vat_number', ''),    
-  );
-
-  // Build array for selecting the default template
-  $a_default_template = array();
-  foreach ($a_templates as $s_template) {
-    $a_default_template[$s_template] = ucfirst($s_template);
-  }
-
-  $form['general']['default_template'] = array(
-    '#type' => 'select',
-    '#title' => t('Default template'),
-    '#options' => $a_default_template,
-    '#default_value' => variable_get('invoice_default_template', 'default'),
-    '#required' => TRUE,
-    '#size' => 1,
-  );
-
-  /*------------------------------------------------------*/
-  // Build form for template values
-
-  foreach ($a_templates as $s_template) {
-    $form[$s_template] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Template') .' ('. $s_template .')',
-      '#collapsible' => TRUE,
-      '#collapsed' => $s_template == 'default' ? FALSE : TRUE,
-      '#description' => t('If fields are also set in invoice general settings and the template field is empty, the general setting of the field will be used.'),
-    );
-    $form[$s_template][$s_template .'_locale'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Locale'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'locale', ''),
-      '#description' => t('Category/locale names can be found in !rfc1766 and !iso639. Systems can have different naming schemes for locales.',
-    array(
-         '!rfc1766' => l('» RFC 1766', 'http://www.faqs.org/rfcs/rfc1766', array('absolute' => TRUE)),
-         '!iso639' => l('» ISO 639', 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm', array('absolute' => TRUE)),
-    )
-    ) .' '. t('On linux you can check the available locales on the server with the command "locale -a" or click below to see the same list.')
-    .' '. t('If your system/server is ubuntu (debian like) you can install more languages with the aptitude or synaptic package manager. Search for -language-pack-*-base.')
-    .' '. t('If you install for example -language-pack-en-base you get over 10+ locales extra, like en_US, en_GB, en_AU, en_CA etc.')
-    .' '. t('For more information see !link.', array('!link' => l('http://www.php.net/setlocale', 'http://www.php.net/setlocale', array('absolute' => TRUE))))
-    .' '. l('Click here to see an overview of installed locales on your system.', 'invoice/installed_locales'),
-      '#size' => 20,
-    );
-    $form[$s_template][$s_template .'_date_format'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Date format'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'date_format', ''),
-      '#description' => t('The date on the invoice will look like: @date_format', array('@date_format' => date(_invoice_get_variable($s_template, 'date_format')))),
-      '#size' => 20,
-    );
-    $form[$s_template][$s_template .'_vat'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Default vat percentage'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'vat', ''),
-      '#size' => 3,
-    );
-    $form[$s_template][$s_template .'_pay_limit'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Pay limit'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'pay_limit', ''),
-      '#description' => t('Pay limit in days'),
-      '#size' => 3,
-    );
-
-    /*------------------------------------------------------*/
-     
-    $s_fieldset_name = '_display_column';
-
-    $form[$s_template][$s_template .'_display_column'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Display invoice columns'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_vat'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('VAT'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'display_column_vat', ''),    
-    );
-    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_exunitcost'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Unitcost (ex)'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'display_column_exunitcost', ''),    
-    );
-    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_incunitcost'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Unitcost (inc)'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'display_column_incunitcost', ''),    
-    );
-    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_extotal'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Total (ex)'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'display_column_extotal', ''),    
-    );
-    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_inctotal'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Total (inc)'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'display_column_inctotal', ''),    
-    );
-     
-    /*------------------------------------------------------*/
-
-    $form[$s_template][$s_template .'_supplier'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Supplier details'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_company_name'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Company name'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_company_name', ''),    
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_street'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Street'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_street', ''),    
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_building_number'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Building number'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_building_number', ''),    
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_zipcode'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Zipcode'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_zipcode', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_city'] = array(
-      '#type' => 'textfield',
-      '#title' => t('City'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_city', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_country'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Country'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_country', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_phone'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Phone'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_phone', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_fax'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Fax'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_fax', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_email'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Email'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_email', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_web'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Web address'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_web', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_coc_number'] = array(
-      '#type' => 'textfield',
-      '#title' => t('CoC number'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_coc_number', ''),
-    );
-    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_vat_number'] = array(
-      '#type' => 'textfield',
-      '#title' => t('VAT number'),
-      '#required' => FALSE,
-      '#default_value' => _invoice_get_variable($s_template, 'supplier_vat_number', ''),
-    );
-  }
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Submit'),
-  );
-
-  return $form;
-}
-
-/**
- * Form helper function to get all invoice items
- *
- * @param string $type
- * @param integer $invoice_id
- *
- * @return array
- */
-function _invoice_get_invoice_items($invoice_id=0, $type=NULL) {
-  $i = 0;
-  $invoice_id = intval($invoice_id);
-
-  $invoice_items_table_rows = array();
-  $sql_addition = $invoice_id > 0 ? ' '. intval($invoice_id) : '';
-
-  $result = db_query("SELECT * FROM {invoice_items} WHERE uid=%d AND invoice_id=%d ORDER BY created ASC",
-      $GLOBALS['user']->uid,
-      $invoice_id
-  );
-
-  // implement hook_form() here
-  
-  $form['page_names'] = array();
-  $form['page_weights'] = array();
-
-  $weight_column = array(
-    '#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => 20,
-    '#delta' => 10,
-    '#access' => TRUE,
-    '#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
-  );
-  
-  $weight_column = process_weight($weight_column);
-            
-  while ($row = db_fetch_object($result)) {
-    $i++;
-    $invoice_items_table_rows[] = array(
-      'data' => array(
-        nl2br($row->description),
-        $row->vat .'%',
-        $row->quantity,
-        _invoice_round_and_format_money($row->unitcost, 3),
-        _invoice_round_and_format_money($row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
-        _invoice_round_and_format_money($row->quantity * $row->unitcost, 2),
-        _invoice_round_and_format_money($row->quantity * $row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
-        array('data' =>
-          drupal_render($weight_column)
-          .
-          _invoice_get_icon('edit', NULL, array(
-            'onclick' => sprintf("invoice_edit_item('%d')", $row->iid),
-            'class' => 'mouse-pointer',
-            'title' => t('Edit'),
-          ))
-          .
-          _invoice_get_icon('delete', NULL, array(
-            'onclick' => sprintf("invoice_delete_item('%d')", $row->iid),
-            'class' => 'mouse-pointer',
-            'title' => t('Delete'),
-          )),
-          'class' => 'actions'
-        ),
-      ),
-      'class' => $type .'item-'. $row->iid .' invoice-item draggable',
-    );
-  }
-
-  return array('rows' => $invoice_items_table_rows, 'count' => $i);
-}
-
-
-/**
- * Implementation of hook_form_alter()
- *
- * @param array $form
- * @param array $form_state
- * @param string $form_id
- */
-function invoice_form_alter(&$form, $form_state, $form_id) {
-  if ($form_id == 'invoice_node_form') {
-    unset($form['buttons']['preview']);
-  }
+<?php
+// $Id: invoice_form.inc,v 1.1.2.4 2009/01/02 21:24:23 pvogelaar Exp $
+
+/**
+ * @file
+ * Invoice module
+ *
+ * This module was developed by Platina Designs, http://www.platinadesigns.nl
+ *
+ * @author Pieter Vogelaar <ps.vogelaar@platinadesigns.nl>
+ */
+
+/**
+ * Implementatin of node_form()
+ */
+function invoice_form(&$form_state, $node) {
+  _invoice_add_css_js();
+
+  //drupal_add_tabledrag('invoice-items-table', 'order', 'sibling', 'invoice-item', $subgroup = NULL, $source = NULL, $hidden = TRUE, $limit = 0);
+  
+  // If an invoice number is available we are in editing mode
+  if (!empty($form_state->invoice['invoice_number'])) {
+    $mode = 'edit';
+  }
+  else {
+    $mode = 'create';
+  }
+
+  $form = array();
+  $form['invoice_template'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Invoice template'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 1,    
+  );
+
+  // Get template names
+  $a_templates = _invoice_get_templates();
+
+  // Build array for selecting the default template
+  $a_template_options = array();
+  foreach ($a_templates as $s_template) {
+    $a_template_options[$s_template] = ucfirst($s_template);
+  }
+
+  $active_template = empty($form_state->invoice['template']) ? _invoice_get_chosen_template() : $form_state->invoice['template'];
+
+  $form['invoice_template']['template'] = array(
+    '#type' => 'select',
+    '#title' => '',
+    '#options' => $a_template_options,
+    '#default_value' => $active_template,
+    '#attributes' => empty($form_state->invoice['template']) ? array('onchange' => 'invoice_set_template(this.value)') : array(),
+    '#description' => t("When editing this invoice, you'll have to save first before you can see template changes."),
+  );
+
+  if (empty($form_state->invoice['template'])) {
+    $_SESSION['invoice_template'] = _invoice_get_chosen_template();
+  }
+  $access_users = array();
+  if(isset($form_state->nid) && $form_state->nid)
+  {
+    $db_access_users = db_query('SELECT name FROM {users} AS u JOIN {invoice_access_users} AS iau ON u.uid = iau.uid WHERE iau.nid = %d', $form_state->nid);
+    while($access_user = db_fetch_array($db_access_users)) {
+      $access_users[] = $access_user['name'];
+    }
+  }
+  $access_users = (count($access_users)) ? implode(', ', $access_users) : FALSE;
+  $form['invoice_access_users'] = array
+  (
+    '#title' => t('Provide access to this invoice to the following users'),
+    '#type' => 'textfield',
+    '#required' => TRUE,
+    '#autocomplete_path' => 'invoice/autocomplete/users_multiple',
+    '#description' => t('Enter a comma separated list of users who should have access to this invoice'),
+    '#default_value' => $access_users,
+  );
+
+  $form['customer'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Customer details'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#description' => t('You either have to fill in Company name or Lastname. Firstname is optional and is only saved if a Lastname is filled in.'),
+    '#weight' => 2,
+  );
+  $form['customer']['search'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Search customer'),
+    '#maxlength' => 60,
+    '#autocomplete_path' => 'invoice/search/customer',
+    '#default_value' => !empty($form_state->customer['company_name']) ? $form_state->customer['company_name'] : $form_state->customer['lastname'] . (!empty($form_state->customer['firstname']) ? ', '. $form_state->customer['firstname'] : ''),
+  );
+  $form['customer']['company_name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Company name'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['company_name'],
+  );
+  $form['customer']['firstname'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Firstname'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['firstname'],
+  );
+  $form['customer']['lastname'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Lastname'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['lastname'],
+  );
+
+  $invoice_items_table_header = array(
+  t('Description'),
+  t('VAT'),
+  t('Count'),
+  t('Unitcost (ex. VAT)'),
+  t('Unitcost (inc. VAT)'),
+  t('Subtotal (ex. VAT)'),
+  t('Subtotal (inc. VAT)'),
+    '',
+  );
+
+  $form['invoice_items'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Invoice items'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 4,
+  );
+
+  // Set locale so money has the right format for the preferred culture
+  if (intval($form_state->invoice['invoice_number']) == 0) {
+    if ($locale = _invoice_get_variable(_invoice_get_chosen_template(), 'locale')) {
+      setlocale(LC_MONETARY, $locale);
+    }
+  }
+  elseif ($locale = _invoice_get_variable($active_template, 'locale')) {
+    setlocale(LC_MONETARY, $locale);
+  }
+
+  // Get invoice items
+  $a_items = _invoice_get_invoice_items($form_state->invoice['invoice_number']);
+  $count = $a_items['count'];
+  $invoice_items_table_rows = $a_items['rows'];
+
+  // If now rows are found add an empty row
+  if ($count == 0) {
+    $invoice_items_table_rows = array(
+      array(
+        'data' => array(array('data' => t('Empty') .'...', 'colspan' => '7')),
+        'class' => 'invoice-items-empty'          
+      ),
+    );
+  }
+  else {
+    // Count the added items
+    $a_totals = _invoice_get_invoice_totals($form_state->invoice['invoice_number'], $GLOBALS['user']->uid);
+    $total->extotal = $a_totals['extotal'];
+    $total->inctotal = $a_totals['inctotal'];
+  }
+
+  $invoice_items_table = theme('invoice_table', $invoice_items_table_header, $invoice_items_table_rows, array('id' => 'invoice-items-table', 'disable_sticky_header' => TRUE));
+  $invoice_items_table_footer = '<tfoot><tr><td colspan="5"></td><td class="extotal">'. _invoice_round_and_format_money($total->extotal, 2) .'</td><td class="inctotal">'. _invoice_round_and_format_money($total->inctotal, 2) .'</td><td></td></tr></tfoot>';
+  $invoice_items_table = str_replace('</table>', $invoice_items_table_footer .'</table>', $invoice_items_table);
+
+  $form['invoice_items']['items'] = array(
+    '#value' => '<div class="invoice-items">'. $invoice_items_table .'</div>',    
+  );
+  $form['invoice_items']['iid'] = array(
+    '#type' => 'hidden',
+    '#title' => t('Invoice item id'),
+    '#required' => FALSE,
+  );
+  $form['invoice_items']['description'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#required' => FALSE,
+    '#rows' => 1,
+  );
+  $form['invoice_items']['quantity'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Quantity'),
+    '#required' => FALSE,
+    '#size' => 5,
+  );
+  $form['invoice_items']['price_without_vat'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Price without VAT'),
+    '#required' => FALSE,
+    '#description' => t("If you don't fill in this field, you'll have to fill in \"Price with VAT\""),
+  );
+  $form['invoice_items']['price_with_vat'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Price with VAT'),
+    '#required' => FALSE,
+    '#description' => t("If you don't fill in this field, you'll have to fill in \"Price without VAT\""),
+  );
+  $form['invoice_items']['vat'] = array(
+    '#type' => 'textfield',
+    '#title' => t('VAT percentage'),
+    '#required' => TRUE,
+    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
+    '#default_value' => _invoice_get_variable($active_template, 'vat'),
+  );
+  $form['invoice_items']['save_item'] = array(
+    '#value' => '<input type="button" id="button-save-item" name="button_save_item" value="'. t('Add item') .'" onclick="invoice_save_item()" />',    
+  );
+
+  $form['customer_optional'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Customer details') .' ('. t('optional') .')',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#weight' => 3, 
+  );
+  $form['customer_optional']['street'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Street'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['street'],
+  );
+  $form['customer_optional']['building_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Building number'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['building_number'],
+  );
+  $form['customer_optional']['zipcode'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Zipcode'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['zipcode'],
+  );
+  $form['customer_optional']['city'] = array(
+    '#type' => 'textfield',
+    '#title' => t('City'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['city'],
+  );
+  $form['customer_optional']['country'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Country'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['country'],
+  );
+  $form['customer_optional']['coc_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Chamber of Commerce number'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['coc_number'],
+  );
+  $form['customer_optional']['vat_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('VAT number'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['vat_number'],
+  );
+  $form['customer_optional']['customer_description'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->customer['description'],
+  );
+
+  $form['invoice_details'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Invoice details') .' ('. t('optional') .')',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#weight' => 5,
+  );
+
+  // Only display this form field when creating a node
+  if (empty($form_state->invoice['invoice_number'])) {
+    $form['invoice_details']['user_defined_invoice_number'] = array(
+      '#type' => 'textfield',
+      '#title' => t('User defined invoice number'),
+      '#required' => FALSE,
+      '#default_value' => '',
+      '#attributes' => array('style' => 'width:200px;'), // size attribute didn't work here for some strange reason
+      '#description' => t('You can define an invoice number here. The number has to be higher than the latest invoice number though. It also has to be numeric.'),
+    );
+  }
+  $form['invoice_details']['invoice_number'] = array(
+    '#type' => 'hidden',
+    '#title' => t('Invoice number'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->invoice['invoice_number'],
+  );
+  $form['invoice_details']['pay_limit'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Pay limit'),
+    '#required' => FALSE,
+    '#default_value' => empty($form_state->invoice['pay_limit']) ? _invoice_get_variable($active_template, 'pay_limit') : $form_state->invoice['pay_limit'],
+    '#description' => t('Pay limit in days'),
+    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
+  );
+  $form['invoice_details']['invoice_description'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#required' => FALSE,
+    '#default_value' => $form_state->invoice['description'],
+  );
+  $form['invoice_details']['invoice_invoice_number_zerofill'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Invoice number zerofill'),
+    '#required' => FALSE,
+    '#default_value' => empty($form_state->invoice['invoice_number_zerofill']) && $mode == 'create' ? variable_get('invoice_invoice_number_zerofill', 0) : $form_state->invoice['invoice_number_zerofill'],
+    '#attributes' => array('style' => 'width:40px;'), // size attribute didn't work here for some strange reason
+    '#description' => t('If you want an invoice number to be displayed as "0001" fill in 4. If you just want to display invoice number "1" leave/set empty.'),
+  );
+  $form['invoice_details']['invoice_invoice_number_prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Invoice number prefix'),
+    '#required' => FALSE,
+    '#default_value' => empty($form_state->invoice['invoice_number_prefix']) && $mode == 'create' ? variable_get('invoice_invoice_number_prefix', '') : $form_state->invoice['invoice_number_prefix'],
+    '#attributes' => array('style' => 'width:150px;'), // size attribute didn't work here for some strange reason
+    '#description' => t('If you want an invoice number to be displayed as "@year0001" fill in "%Y". Fillin 4 in the zerofill field above for extra zero values.', array('@year' => date('Y')))
+  .' '. t('If a new year is reached the numbering will still continue sequentially, so if the year ended with "@year0578", the next year will start with "@next_year0579"', array('@year' => date('Y'), '@next_year' => date('Y') + 1))
+  .' '. t('All !date values may be entered here with a "%" sign before it or every other text you like.', array('!date' => l('date', 'http://www.php.net/date', array('absolute' => TRUE)))),
+  );
+
+  return $form;
+}
+
+/**
+ * Invoice settings form
+ */
+function invoice_settings_form() {
+
+  // Get template names
+  $a_templates = _invoice_get_templates();
+
+  $form['general'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('General settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,    
+  );
+  $form['general']['locale'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Locale'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('invoice_locale', ''),
+    '#description' => t('Category/locale names can be found in !rfc1766 and !iso639. Systems can have different naming schemes for locales.',
+  array(
+       '!rfc1766' => l('» RFC 1766', 'http://www.faqs.org/rfcs/rfc1766', array('absolute' => TRUE)),
+       '!iso639' => l('» ISO 639', 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm', array('absolute' => TRUE)),
+  )
+  ) .' '. t('On linux you can check the available locales on the server with the command "locale -a" or click below to see the same list.')
+  .' '. t('If your system/server is ubuntu (debian like) you can install more languages with the aptitude or synaptic package manager. Search for -language-pack-*-base.')
+  .' '. t('If you install for example -language-pack-en-base you get over 10+ locales extra, like en_US, en_GB, en_AU, en_CA etc.')
+  .' '. t('For more information see !link.', array('!link' => l('http://www.php.net/setlocale', 'http://www.php.net/setlocale', array('absolute' => TRUE))))
+  .' '. l('Click here to see an overview of installed locales on your system.', 'invoice/installed_locales'),
+    '#size' => 8,
+  );
+  $form['general']['date_format'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Date format'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('invoice_date_format', ''),
+    '#description' => t('The date on the invoice will look like: @date_format', array('@date_format' => date(variable_get('invoice_date_format', '')))),
+    '#size' => 20,
+  );
+  $form['general']['vat'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Default VAT precentage'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('invoice_vat', ''),
+    '#size' => 3,
+  );
+  $form['general']['pay_limit'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Pay limit'),
+    '#required' => TRUE,
+    '#default_value' => variable_get('invoice_pay_limit', ''),
+    '#description' => t('Pay limit in days'),
+    '#size' => 3,
+  );
+  $form['general']['invoice_number_zerofill'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Invoice number zerofill'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_invoice_number_zerofill', ''),
+    '#description' => t('If you want an invoice number to be displayed as "0001" fill in 4. If you just want to display invoice number "1" leave/set empty.'),
+    '#size' => 3,
+  );
+  $form['general']['invoice_number_prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Invoice number prefix'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_invoice_number_prefix', ''),
+    '#description' => t('If you want an invoice number to be displayed as "@year0001" fill in "%Y". Fillin 4 in the zerofill field above for extra zero values.', array('@year' => date('Y')))
+  .' '. t('If a new year is reached the numbering will still continue sequentially, so if the year ended with "@year0578", the next year will start with "@next_year0579"', array('@year' => date('Y'), '@next_year' => date('Y') + 1))
+  .' '. t('All !date values may be entered here with a "%" sign before it or every other text you like.', array('!date' => l('date', 'http://www.php.net/date', array('absolute' => TRUE)))),
+    '#size' => 20,
+  );
+
+  /*------------------------------------------------------*/
+
+  $form['general']['display_column'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Display invoice columns'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['general']['display_column']['display_column_vat'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('VAT'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_display_column_vat', ''),    
+  );
+  $form['general']['display_column']['display_column_exunitcost'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Unitcost (ex)'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_display_column_exunitcost', ''),    
+  );
+  $form['general']['display_column']['display_column_incunitcost'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Unitcost (inc)'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_display_column_incunitcost', ''),    
+  );
+  $form['general']['display_column']['display_column_extotal'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Total (ex)'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_display_column_extotal', ''),    
+  );
+  $form['general']['display_column']['display_column_inctotal'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Total (inc)'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_display_column_inctotal', ''),    
+  );
+
+  /*------------------------------------------------------*/
+
+  $form['general']['supplier'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Supplier details'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $form['general']['supplier']['supplier_company_name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Company name'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_company_name', ''),    
+  );
+  $form['general']['supplier']['supplier_street'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Street'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_street', ''),    
+  );
+  $form['general']['supplier']['supplier_building_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Building number'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_building_number', ''),    
+  );
+  $form['general']['supplier']['supplier_zipcode'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Zipcode'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_zipcode', ''),    
+  );
+  $form['general']['supplier']['supplier_city'] = array(
+    '#type' => 'textfield',
+    '#title' => t('City'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_city', ''),    
+  );
+  $form['general']['supplier']['supplier_country'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Country'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_country', ''),    
+  );
+  $form['general']['supplier']['supplier_phone'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Phone'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_phone', ''),    
+  );
+  $form['general']['supplier']['supplier_fax'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Fax'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_fax', ''),    
+  );
+  $form['general']['supplier']['supplier_email'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Email'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_email', ''),    
+  );
+  $form['general']['supplier']['supplier_web'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Web address'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_web', ''),    
+  );
+  $form['general']['supplier']['supplier_coc_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('CoC Number'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_coc_number', ''),    
+  );
+  $form['general']['supplier']['supplier_vat_number'] = array(
+    '#type' => 'textfield',
+    '#title' => t('VAT Number'),
+    '#required' => FALSE,
+    '#default_value' => variable_get('invoice_supplier_vat_number', ''),    
+  );
+
+  // Build array for selecting the default template
+  $a_default_template = array();
+  foreach ($a_templates as $s_template) {
+    $a_default_template[$s_template] = ucfirst($s_template);
+  }
+
+  $form['general']['default_template'] = array(
+    '#type' => 'select',
+    '#title' => t('Default template'),
+    '#options' => $a_default_template,
+    '#default_value' => variable_get('invoice_default_template', 'default'),
+    '#required' => TRUE,
+    '#size' => 1,
+  );
+
+  /*------------------------------------------------------*/
+  // Build form for template values
+
+  foreach ($a_templates as $s_template) {
+    $form[$s_template] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Template') .' ('. $s_template .')',
+      '#collapsible' => TRUE,
+      '#collapsed' => $s_template == 'default' ? FALSE : TRUE,
+      '#description' => t('If fields are also set in invoice general settings and the template field is empty, the general setting of the field will be used.'),
+    );
+    $form[$s_template][$s_template .'_locale'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Locale'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'locale', ''),
+      '#description' => t('Category/locale names can be found in !rfc1766 and !iso639. Systems can have different naming schemes for locales.',
+    array(
+         '!rfc1766' => l('» RFC 1766', 'http://www.faqs.org/rfcs/rfc1766', array('absolute' => TRUE)),
+         '!iso639' => l('» ISO 639', 'http://www.w3.org/WAI/ER/IG/ert/iso639.htm', array('absolute' => TRUE)),
+    )
+    ) .' '. t('On linux you can check the available locales on the server with the command "locale -a" or click below to see the same list.')
+    .' '. t('If your system/server is ubuntu (debian like) you can install more languages with the aptitude or synaptic package manager. Search for -language-pack-*-base.')
+    .' '. t('If you install for example -language-pack-en-base you get over 10+ locales extra, like en_US, en_GB, en_AU, en_CA etc.')
+    .' '. t('For more information see !link.', array('!link' => l('http://www.php.net/setlocale', 'http://www.php.net/setlocale', array('absolute' => TRUE))))
+    .' '. l('Click here to see an overview of installed locales on your system.', 'invoice/installed_locales'),
+      '#size' => 20,
+    );
+    $form[$s_template][$s_template .'_date_format'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Date format'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'date_format', ''),
+      '#description' => t('The date on the invoice will look like: @date_format', array('@date_format' => date(_invoice_get_variable($s_template, 'date_format')))),
+      '#size' => 20,
+    );
+    $form[$s_template][$s_template .'_vat'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Default vat percentage'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'vat', ''),
+      '#size' => 3,
+    );
+    $form[$s_template][$s_template .'_pay_limit'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Pay limit'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'pay_limit', ''),
+      '#description' => t('Pay limit in days'),
+      '#size' => 3,
+    );
+
+    /*------------------------------------------------------*/
+     
+    $s_fieldset_name = '_display_column';
+
+    $form[$s_template][$s_template .'_display_column'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Display invoice columns'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_vat'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('VAT'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'display_column_vat', ''),    
+    );
+    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_exunitcost'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Unitcost (ex)'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'display_column_exunitcost', ''),    
+    );
+    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_incunitcost'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Unitcost (inc)'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'display_column_incunitcost', ''),    
+    );
+    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_extotal'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Total (ex)'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'display_column_extotal', ''),    
+    );
+    $form[$s_template][$s_template .'_display_column'][$s_template . $s_fieldset_name .'_inctotal'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Total (inc)'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'display_column_inctotal', ''),    
+    );
+     
+    /*------------------------------------------------------*/
+
+    $form[$s_template][$s_template .'_supplier'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Supplier details'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_company_name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Company name'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_company_name', ''),    
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_street'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Street'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_street', ''),    
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_building_number'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Building number'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_building_number', ''),    
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_zipcode'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Zipcode'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_zipcode', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_city'] = array(
+      '#type' => 'textfield',
+      '#title' => t('City'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_city', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_country'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Country'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_country', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_phone'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Phone'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_phone', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_fax'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Fax'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_fax', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_email'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Email'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_email', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_web'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Web address'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_web', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_coc_number'] = array(
+      '#type' => 'textfield',
+      '#title' => t('CoC number'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_coc_number', ''),
+    );
+    $form[$s_template][$s_template .'_supplier'][$s_template .'_supplier_vat_number'] = array(
+      '#type' => 'textfield',
+      '#title' => t('VAT number'),
+      '#required' => FALSE,
+      '#default_value' => _invoice_get_variable($s_template, 'supplier_vat_number', ''),
+    );
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit'),
+  );
+
+  return $form;
+}
+
+/**
+ * Form helper function to get all invoice items
+ *
+ * @param string $type
+ * @param integer $invoice_id
+ *
+ * @return array
+ */
+function _invoice_get_invoice_items($invoice_id=0, $type=NULL) {
+  $i = 0;
+  $invoice_id = intval($invoice_id);
+
+  $invoice_items_table_rows = array();
+  $sql_addition = $invoice_id > 0 ? ' '. intval($invoice_id) : '';
+
+  $result = db_query("SELECT * FROM {invoice_items} WHERE uid=%d AND invoice_id=%d ORDER BY created ASC",
+      $GLOBALS['user']->uid,
+      $invoice_id
+  );
+
+  // implement hook_form() here
+  
+  $form['page_names'] = array();
+  $form['page_weights'] = array();
+
+  $weight_column = array(
+    '#type' => 'weight',
+    '#title' => t('Weight'),
+    '#default_value' => 20,
+    '#delta' => 10,
+    '#access' => TRUE,
+    '#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
+  );
+  
+  $weight_column = process_weight($weight_column);
+            
+  while ($row = db_fetch_object($result)) {
+    $i++;
+    $invoice_items_table_rows[] = array(
+      'data' => array(
+        nl2br($row->description),
+        $row->vat .'%',
+        $row->quantity,
+        _invoice_round_and_format_money($row->unitcost, 3),
+        _invoice_round_and_format_money($row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
+        _invoice_round_and_format_money($row->quantity * $row->unitcost, 2),
+        _invoice_round_and_format_money($row->quantity * $row->unitcost * _invoice_vat_percent_to_decimal($row->vat), 2),
+        array('data' =>
+          drupal_render($weight_column)
+          .
+          _invoice_get_icon('edit', NULL, array(
+            'onclick' => sprintf("invoice_edit_item('%d')", $row->iid),
+            'class' => 'mouse-pointer',
+            'title' => t('Edit'),
+          ))
+          .
+          _invoice_get_icon('delete', NULL, array(
+            'onclick' => sprintf("invoice_delete_item('%d')", $row->iid),
+            'class' => 'mouse-pointer',
+            'title' => t('Delete'),
+          )),
+          'class' => 'actions'
+        ),
+      ),
+      'class' => $type .'item-'. $row->iid .' invoice-item draggable',
+    );
+  }
+
+  return array('rows' => $invoice_items_table_rows, 'count' => $i);
+}
+
+
+/**
+ * Implementation of hook_form_alter()
+ *
+ * @param array $form
+ * @param array $form_state
+ * @param string $form_id
+ */
+function invoice_form_alter(&$form, $form_state, $form_id) {
+  if ($form_id == 'invoice_node_form') {
+    unset($form['buttons']['preview']);
+  }
 }
\ No newline at end of file
