diff --git a/application/controllers/Config.php b/application/controllers/Config.php index 2544010b6..0dce618ae 100644 --- a/application/controllers/Config.php +++ b/application/controllers/Config.php @@ -10,6 +10,7 @@ class Config extends Secure_Controller $this->load->library('barcode_lib'); $this->load->library('sale_lib'); + $this->load->library('tax_lib'); } /* @@ -267,6 +268,9 @@ class Config extends Secure_Controller public function save_general() { + $migrate_sales_history = $this->input->post('migrate_sales_history') != NULL; + $migrate_sales_history_block = $this->input->post('migrate_sales_history_block'); + $batch_save_data = array( 'theme' => $this->input->post('theme'), 'default_tax_1_rate' => parse_decimals($this->input->post('default_tax_1_rate')), @@ -275,6 +279,8 @@ class Config extends Secure_Controller 'default_tax_2_name' => $this->input->post('default_tax_2_name'), 'tax_included' => $this->input->post('tax_included') != NULL, 'customer_sales_tax_support' => $this->input->post('customer_sales_tax_support') != NULL, + 'migrate_sales_history' => $migrate_sales_history, + 'migrate_sales_history_block' => $migrate_sales_history_block, 'default_origin_tax_code' => $this->input->post('default_origin_tax_code'), 'receiving_calculate_average_price' => $this->input->post('receiving_calculate_average_price') != NULL, 'lines_per_page' => $this->input->post('lines_per_page'), @@ -298,10 +304,47 @@ class Config extends Secure_Controller $result = $this->Appconfig->batch_save($batch_save_data); $success = $result ? TRUE : FALSE; - echo json_encode(array( - 'success' => $success, - 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully') - )); + if($success && $migrate_sales_history) + { + $number_of_unmigrated = $this->Sale->get_count_of_unmigrated(); + if ($number_of_unmigrated > 0 && $migrate_sales_history_block > 0) + { + $unmigrated_invoices = $this->Sale->get_unmigrated($migrate_sales_history_block)->result_array(); + + foreach($unmigrated_invoices as $key=>$unmigrated_invoice) + { + $this->tax_lib->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id']); + } + + if($migrate_sales_history_block > $number_of_unmigrated) + { + $migrate_sales_history_block = $number_of_unmigrated; + } + + $number_of_unmigrated = $this->Sale->get_count_of_unmigrated(); + + echo json_encode(array( + 'success' => $success, + 'message' => $this->lang->line('config_saved_with_migration').' '.$migrate_sales_history_block.' / '.$number_of_unmigrated.' '.$this->lang->line('config_migrate_remaining') + )); + + } + else + { + echo json_encode(array( + 'success' => $success, + 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully') + )); + } + } + else + { + echo json_encode(array( + 'success' => $success, + 'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully') + )); + } + } public function check_number_locale() diff --git a/application/language/en/config_lang.php b/application/language/en/config_lang.php index d5e7a152e..0ff09c371 100644 --- a/application/language/en/config_lang.php +++ b/application/language/en/config_lang.php @@ -154,6 +154,10 @@ $lang["config_mailchimp_key_successfully"] = "Valid API Key"; $lang["config_mailchimp_key_unsuccessfully"] = "Invalid API Key"; $lang["config_message"] = "Message"; $lang["config_message_configuration"] = "Message Configuration"; +$lang["config_migrate_remaining"] = "remaining to be migrated"; +$lang["config_migrate_sales_history"] = "Migrate sales history on Save"; +$lang["config_migrate_sales_history_block"] = "Sales to migrate per Save"; +$lang["config_saved_with_migration"] = "Configuration saved and the number of sales migrated is "; $lang["config_msg_msg"] = "Saved Text Message"; $lang["config_msg_msg_placeholder"] = "If you wish to use a SMS template save your message here. Otherwise leave the box blank."; $lang["config_msg_pwd"] = "SMS-API Password"; diff --git a/application/libraries/Tax_lib.php b/application/libraries/Tax_lib.php index 0718dbb9d..e8ea75456 100644 --- a/application/libraries/Tax_lib.php +++ b/application/libraries/Tax_lib.php @@ -89,35 +89,32 @@ class Tax_lib $tax_group_index = $this->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); } } @@ -318,6 +315,45 @@ class Tax_lib return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars. } -} -?> + 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->CI->Sale->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->CI->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->CI->sale_lib->get_item_tax($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], $item['percent']); + } + else + { + $item_tax_amount = $this->get_sales_tax_for_amount($tax_basis, $item['percent'], '0', $tax_decimals); + } + $this->CI->Sale->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount); + $this->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->CI->Sale->save_sales_tax($sales_taxes); + } +} +?> \ No newline at end of file diff --git a/application/models/Sale.php b/application/models/Sale.php index b361407cd..87f9d4f5a 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -752,11 +752,14 @@ class Sale extends CI_Model } } - private function save_sales_tax(&$sales_taxes) + public function save_sales_tax(&$sales_taxes) { + error_log('>>>Sale.save_sales_tax started'.print_r($sales_taxes, TRUE)); foreach($sales_taxes as $line=>$sales_tax) { + error_log('>>>Sale.save_sales_tax $sales_tax - '.print_r($sales_tax, TRUE)); $this->db->insert('sales_taxes', $sales_tax); + error_log('>>>Sale.save_sales_tax sales_tax written'); } } @@ -1205,5 +1208,63 @@ class Sale extends CI_Model return $this->db->get(); } + + public 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(); + } + + public 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(*)']; + } + + public 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; + + } + + public function update_sales_items_taxes_amount($sale_id, $line, $name, $percent, $tax_type, $item_tax_amount) + { + error_log('>>>Sale.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)); + } + } -?> +?> \ No newline at end of file diff --git a/application/views/configs/general_config.php b/application/views/configs/general_config.php index 0c4ad8c25..c30d3a803 100644 --- a/application/views/configs/general_config.php +++ b/application/views/configs/general_config.php @@ -82,7 +82,31 @@ -