diff --git a/application/config/migration.php b/application/config/migration.php index 4b585a65c..d326cc7c5 100644 --- a/application/config/migration.php +++ b/application/config/migration.php @@ -11,7 +11,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | and disable it back when you're done. | */ -$config['migration_enabled'] = FALSE; +$config['migration_enabled'] = TRUE; /* |-------------------------------------------------------------------------- @@ -69,7 +69,7 @@ $config['migration_auto_latest'] = FALSE; | be upgraded / downgraded to. | */ -$config['migration_version'] = 0; +$config['migration_version'] = 20170502221500; /* |-------------------------------------------------------------------------- diff --git a/application/controllers/Migrate.php b/application/controllers/Migrate.php new file mode 100644 index 000000000..ad3452316 --- /dev/null +++ b/application/controllers/Migrate.php @@ -0,0 +1,34 @@ +load->library('migration'); + } + public function index() + + { + $this->load->view('migrate/manage'); + } + + public function perform_migration() + { + if( ! $this->migration->latest()) + { + echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('migrate_failed - '.$this->migration->error_string()))); + } + else + { + echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('migrate_success'))); + } + } + +} + +?> + diff --git a/application/language/en/migrate_lang.php b/application/language/en/migrate_lang.php new file mode 100644 index 000000000..fa65cbd02 --- /dev/null +++ b/application/language/en/migrate_lang.php @@ -0,0 +1,8 @@ +clean('X'.$tax_group); - if ($item_tax_amount != 0) + if(!array_key_exists($tax_group_index, $sales_taxes)) { - if(!array_key_exists($tax_group_index, $sales_taxes)) - { - $insertkey = $tax_group_index; + $insertkey = $tax_group_index; - $sales_tax = array($insertkey => array( - 'sale_id' => $sale_id, - 'tax_type' => $tax_type, - 'tax_group' => $tax_group, - 'sale_tax_basis' => $tax_basis, - 'sale_tax_amount' => $item_tax_amount, - 'print_sequence' => $tax_group_sequence, - 'name' => $name, - 'tax_rate' => $tax_rate, - 'sales_tax_code' => $tax_code, - 'rounding_code' => $rounding_code - )); + $sales_tax = array($insertkey => array( + 'sale_id' => $sale_id, + 'tax_type' => $tax_type, + 'tax_group' => $tax_group, + 'sale_tax_basis' => $tax_basis, + 'sale_tax_amount' => $item_tax_amount, + 'print_sequence' => $tax_group_sequence, + 'name' => $name, + 'tax_rate' => $tax_rate, + 'sales_tax_code' => $tax_code, + 'rounding_code' => $rounding_code + )); - //add to existing array - $sales_taxes += $sales_tax; - } - else - { - // Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4 - // but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes - $sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4); - $sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4); - } + //add to existing array + $sales_taxes += $sales_tax; + } + else + { + // Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4 + // but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes + $sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4); + $sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4); } } @@ -140,7 +137,7 @@ class Tax_lib foreach($sales_taxes as $row_number => $sales_tax) { - $sales_tax['sale_tax_amount'] = get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['sale_tax_rate'], $sales_tax['rounding_code'], $currency_decimals); + $sales_taxes[$row_number]['sale_tax_amount'] = $this->get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['tax_rate'], $sales_tax['rounding_code'], $currency_decimals); } } @@ -318,6 +315,6 @@ class Tax_lib return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. } -} -?> +} +?> \ No newline at end of file diff --git a/application/migrations/20170502221506_sales_tax_data.php b/application/migrations/20170502221506_sales_tax_data.php new file mode 100644 index 000000000..c22873595 --- /dev/null +++ b/application/migrations/20170502221506_sales_tax_data.php @@ -0,0 +1,138 @@ +load->library('tax_lib'); + $this->load->library('sale_lib'); + $CI =& get_instance(); + + } + public function up() + { + $number_of_unmigrated = $this->get_count_of_unmigrated(); + error_log('Migrating sales tax history. The number of sales that will be migrated is '.$number_of_unmigrated); + if ($number_of_unmigrated > 0) + { + $unmigrated_invoices = $this->get_unmigrated($number_of_unmigrated)->result_array(); + + foreach($unmigrated_invoices as $key=>$unmigrated_invoice) + { + $this->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id']); + } + } + error_log('Migrating sales tax history. The number of sales that will be migrated is finished.'); + } + + public function down() + { + + } + + private function upgrade_tax_history_for_sale($sale_id) + { + $tax_decimals = $this->CI->config->config['tax_decimals']; + $tax_included = $this->CI->config->config['tax_included']; + + if($tax_included) + { + $tax_type = Tax_lib::TAX_TYPE_VAT; + } + else + { + $tax_type = Tax_lib::TAX_TYPE_SALES; + } + + $sales_taxes = array(); + $tax_group_sequence = 0; + + $items = $this->get_sale_items_for_migration($sale_id)->result_array(); + foreach($items as $item) + { + // This computes tax for each line item and adds it to the tax type total + $tax_group = (float)$item['percent'] . '% ' . $item['name']; + $tax_basis = $this->sale_lib->get_item_total($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], TRUE); + $item_tax_amount = 0; + if($tax_included) + { + $item_tax_amount = $this->sale_lib->get_item_tax($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], $item['percent']); + } + else + { + $item_tax_amount = $this->tax_lib->get_sales_tax_for_amount($tax_basis, $item['percent'], '0', $tax_decimals); + } + $this->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount); + $this->tax_lib->update_sales_taxes($sales_taxes, $tax_type, $tax_group, $item['percent'], $tax_basis, $item_tax_amount, $tax_group_sequence, '0', $sale_id, $item['name']); + $tax_group_sequence += 1; + } + $this->tax_lib->apply_invoice_taxing($sales_taxes); + + $this->save_sales_tax($sales_taxes); + } + + private function get_unmigrated($block_count) + { + + $this->db->select('SIT.sale_id'); + $this->db->select('ST.sale_id as sales_taxes_sale_id'); + $this->db->from('sales_items_taxes as SIT'); + $this->db->join('sales_taxes as ST','SIT.sale_id = ST.sale_id', 'left'); + $this->db->where('ST.sale_id is null'); + $this->db->group_by('SIT.sale_id'); + $this->db->group_by('ST.sale_id'); + $this->db->order_by('SIT.sale_id'); + $this->db->limit($block_count); + $query = $this->db->get(); + + return $query; + + } + + private function get_sale_items_for_migration($sale_id) + { + $this->db->select('sales_items.sale_id as sale_id'); + $this->db->select('sales_items.line as line'); + $this->db->select('item_unit_price'); + $this->db->select('discount_percent'); + $this->db->select('quantity_purchased'); + $this->db->select('percent'); + $this->db->select('name'); + $this->db->from('sales_items as sales_items'); + $this->db->join('sales_items_taxes as sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id and sales_items.line = sales_items_taxes.line'); + $this->db->where('sales_items.sale_id', $sale_id); + + return $this->db->get(); + } + + private function get_count_of_unmigrated() + { + $result = $this->db->query('SELECT COUNT(*) FROM(SELECT SIT.sale_id, ST.sale_id as sales_taxes_sale_id FROM ' + . $this->db->dbprefix('sales_items_taxes') + . ' as SIT LEFT JOIN ' + . $this->db->dbprefix('sales_taxes') + . ' as ST ON SIT.sale_id = ST.sale_id WHERE ST.sale_id is null GROUP BY SIT.sale_id, ST.sale_id' + . ' ORDER BY SIT.sale_id) as US')->result_array(); + + return $result[0]['COUNT(*)']; + } + + private function update_sales_items_taxes_amount($sale_id, $line, $name, $percent, $tax_type, $item_tax_amount) + { + $this->db->where('sale_id', $sale_id); + $this->db->where('line', $line); + $this->db->where('name', $name); + $this->db->where('percent', $percent); + $this->db->update('sales_items_taxes', array('tax_type' => $tax_type, 'item_tax_amount' => $item_tax_amount)); + } + + private function save_sales_tax(&$sales_taxes) + { + foreach($sales_taxes as $line=>$sales_tax) + { + $this->db->insert('sales_taxes', $sales_tax); + } + } +} diff --git a/application/models/Sale.php b/application/models/Sale.php index e2ec407e6..9740f720f 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -752,7 +752,7 @@ class Sale extends CI_Model } } - private function save_sales_tax(&$sales_taxes) + public function save_sales_tax(&$sales_taxes) { foreach($sales_taxes as $line=>$sales_tax) { @@ -1205,5 +1205,6 @@ class Sale extends CI_Model return $this->db->get(); } + } -?> +?> \ No newline at end of file diff --git a/application/views/migrate/manage.php b/application/views/migrate/manage.php new file mode 100644 index 000000000..323076de4 --- /dev/null +++ b/application/views/migrate/manage.php @@ -0,0 +1,45 @@ +load->view("partial/header"); ?> + +'start_migration_form','method'=>'post', 'class'=>'form-horizontal')); ?> +
+ +
+ +
+ lang->line('migrate_info'); ?> +
+
+ +
+
+ lang->line('migrate_backup'); ?> +
+
+ + + 'submit_form', + 'id'=>'submit_form', + 'value'=>$this->lang->line('migrate_start'), + 'class'=>'btn btn-primary btn-sm pull-right'));?> +
+ + +load->view("partial/footer"); ?> + + diff --git a/database/3.0.2_to_3.1.0.sql b/database/3.0.2_to_3.1.0.sql index d9d6cebfa..d2f22a93c 100644 --- a/database/3.0.2_to_3.1.0.sql +++ b/database/3.0.2_to_3.1.0.sql @@ -228,3 +228,15 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES ('giftcard_number', 'seri -- add option to print company name in receipt INSERT INTO `ospos_app_config` (`key`, `value`) VALUES ('receipt_show_company_name', '1'); + +-- add support for sales tax history migration + +INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_id`) VALUES + ('module_migrate', 'module_migrate_desc', 120, 'migrate'); + +INSERT INTO `ospos_permissions` (`permission_id`, `module_id`) VALUES + ('migrate', 'migrate'); + +INSERT INTO `ospos_grants` (`permission_id`, `person_id`) VALUES + ('migrate', 1); + diff --git a/database/database.sql b/database/database.sql index 116f52a1b..c16d0aef2 100644 --- a/database/database.sql +++ b/database/database.sql @@ -341,6 +341,7 @@ INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_i ('module_items', 'module_items_desc', 20, 'items'), ('module_item_kits', 'module_item_kits_desc', 30, 'item_kits'), ('module_messages', 'module_messages_desc', 100, 'messages'), +('module_migrate', 'module_migrate_desc', 120, 'migrate'), ('module_receivings', 'module_receivings_desc', 60, 'receivings'), ('module_reports', 'module_reports_desc', 50, 'reports'), ('module_sales', 'module_sales_desc', 70, 'sales'), @@ -414,6 +415,7 @@ INSERT INTO `ospos_permissions` (`permission_id`, `module_id`) VALUES ('items', 'items'), ('item_kits', 'item_kits'), ('messages', 'messages'), +('migrate', 'migrate'), ('receivings', 'receivings'), ('reports', 'reports'), ('sales', 'sales'), @@ -461,6 +463,7 @@ INSERT INTO `ospos_grants` (`permission_id`, `person_id`) VALUES ('items', 1), ('item_kits', 1), ('messages', 1), +('migrate', 1), ('receivings', 1), ('reports', 1), ('sales', 1), diff --git a/database/tables.sql b/database/tables.sql index 43fecdf00..b36194a2d 100644 --- a/database/tables.sql +++ b/database/tables.sql @@ -341,6 +341,7 @@ INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_i ('module_items', 'module_items_desc', 20, 'items'), ('module_item_kits', 'module_item_kits_desc', 30, 'item_kits'), ('module_messages', 'module_messages_desc', 100, 'messages'), +('module_migrate', 'module_migrate_desc', 120, 'migrate'), ('module_receivings', 'module_receivings_desc', 60, 'receivings'), ('module_reports', 'module_reports_desc', 50, 'reports'), ('module_sales', 'module_sales_desc', 70, 'sales'), @@ -414,6 +415,7 @@ INSERT INTO `ospos_permissions` (`permission_id`, `module_id`) VALUES ('items', 'items'), ('item_kits', 'item_kits'), ('messages', 'messages'), +('migrate', 'migrate'), ('receivings', 'receivings'), ('reports', 'reports'), ('sales', 'sales'), @@ -461,6 +463,7 @@ INSERT INTO `ospos_grants` (`permission_id`, `person_id`) VALUES ('items', 1), ('item_kits', 1), ('messages', 1), +('migrate', 1), ('receivings', 1), ('reports', 1), ('sales', 1), diff --git a/public/images/menubar/migrate.png b/public/images/menubar/migrate.png new file mode 100644 index 000000000..c7f4563a4 Binary files /dev/null and b/public/images/menubar/migrate.png differ