function get_item_kits_barcode_data($item_kits_ids)
{
    $CI =& get_instance();
    $result = array();
    $item_kit_ids = explode('~', $item_kits_ids);
    foreach ($item_kit_ids as $item_kit_id) {
        $item_kit_info = $CI->Item_kit->get_info($item_kit_id);
        $item_kit_location_info = $CI->Item_kit_location->get_info($item_kit_id);
        $item_kit_price = $item_kit_location_info->unit_price ? $item_kit_location_info->unit_price : $item_kit_info->unit_price;
        if ($CI->config->item('barcode_price_include_tax')) {
            if ($item_kit_info->tax_included) {
                $result[] = array('name' => to_currency($item_kit_price) . ' ' . $item_kit_info->name, 'id' => 'KIT ' . number_pad($item_kit_id, 10));
            } else {
                $result[] = array('name' => to_currency(get_price_for_item_kit_including_taxes($item_kit_id, $item_kit_price)) . ': ' . $item_kit_info->name, 'id' => 'KIT ' . number_pad($item_kit_id, 10));
            }
        } else {
            if ($item_kit_info->tax_included) {
                $result[] = array('name' => to_currency(get_price_for_item_kit_excluding_taxes($item_kit_id, $item_kit_price)) . ': ' . $item_kit_info->name, 'id' => 'KIT ' . number_pad($item_kit_id, 10));
            } else {
                $result[] = array('name' => to_currency($item_kit_price) . ': ' . $item_kit_info->name, 'id' => 'KIT ' . number_pad($item_kit_id, 10));
            }
        }
    }
    return $result;
}
Example #2
0
    function save($items, $customer_id, $employee_id, $sold_by_employee_id, $comment, $show_comment_on_receipt, $payments, $sale_id = false, $suspended = 0, $cc_ref_no = '', $auth_code = '', $change_sale_date = false, $balance = 0, $store_account_payment = 0)
    {
        //we need to check the sale library for deleted taxes during sale
        $this->load->library('sale_lib');
        if (count($items) == 0) {
            return -1;
        }
        $payment_types = '';
        foreach ($payments as $payment_id => $payment) {
            $payment_types = $payment_types . $payment['payment_type'] . ': ' . to_currency($payment['payment_amount']) . '<br />';
        }
        $tier_id = $this->sale_lib->get_selected_tier_id();
        if (!$tier_id) {
            $tier_id = NULL;
        }
        $sales_data = array('customer_id' => $customer_id > 0 ? $customer_id : null, 'employee_id' => $employee_id, 'sold_by_employee_id' => $sold_by_employee_id, 'payment_type' => $payment_types, 'comment' => $comment, 'show_comment_on_receipt' => $show_comment_on_receipt ? $show_comment_on_receipt : 0, 'suspended' => $suspended, 'deleted' => 0, 'deleted_by' => NULL, 'cc_ref_no' => $cc_ref_no, 'auth_code' => $auth_code, 'location_id' => $this->Employee->get_logged_in_employee_current_location_id(), 'register_id' => $this->Employee->get_logged_in_employee_current_register_id(), 'store_account_payment' => $store_account_payment, 'tier_id' => $tier_id ? $tier_id : NULL);
        if ($sale_id) {
            $old_date = $this->get_info($sale_id)->row_array();
            $sales_data['sale_time'] = $old_date['sale_time'];
            if ($change_sale_date) {
                $sale_time = strtotime($change_sale_date);
                if ($sale_time !== FALSE) {
                    $sales_data['sale_time'] = date('Y-m-d H:i:s', strtotime($change_sale_date));
                }
            }
        } else {
            $sales_data['sale_time'] = date('Y-m-d H:i:s');
        }
        $this->db->query("SET autocommit=0");
        //Lock tables invovled in sale transaction so we don't have deadlock
        $this->db->query('LOCK TABLES ' . $this->db->dbprefix('customers') . ' WRITE, ' . $this->db->dbprefix('sales') . ' WRITE, 
		' . $this->db->dbprefix('store_accounts') . ' WRITE, ' . $this->db->dbprefix('sales_payments') . ' WRITE, ' . $this->db->dbprefix('sales_items') . ' WRITE, 
		' . $this->db->dbprefix('giftcards') . ' WRITE, ' . $this->db->dbprefix('location_items') . ' WRITE, 
		' . $this->db->dbprefix('inventory') . ' WRITE, ' . $this->db->dbprefix('sales_items_taxes') . ' WRITE,
		' . $this->db->dbprefix('sales_item_kits') . ' WRITE, ' . $this->db->dbprefix('sales_item_kits_taxes') . ' WRITE,' . $this->db->dbprefix('people') . ' READ,' . $this->db->dbprefix('items') . ' READ
		,' . $this->db->dbprefix('employees_locations') . ' READ,' . $this->db->dbprefix('locations') . ' READ, ' . $this->db->dbprefix('items_tier_prices') . ' READ
		, ' . $this->db->dbprefix('location_items_tier_prices') . ' READ, ' . $this->db->dbprefix('items_taxes') . ' READ, ' . $this->db->dbprefix('item_kits') . ' READ
		, ' . $this->db->dbprefix('location_item_kits') . ' READ, ' . $this->db->dbprefix('item_kit_items') . ' READ, ' . $this->db->dbprefix('employees') . ' READ , ' . $this->db->dbprefix('item_kits_tier_prices') . ' READ
		, ' . $this->db->dbprefix('location_item_kits_tier_prices') . ' READ, ' . $this->db->dbprefix('location_items_taxes') . ' READ
		, ' . $this->db->dbprefix('location_item_kits_taxes') . ' READ, ' . $this->db->dbprefix('item_kits_taxes') . ' READ');
        $store_account_payment_amount = 0;
        if ($store_account_payment) {
            $store_account_payment_amount = $this->sale_lib->get_total();
        }
        //Only update balance + store account payments if we are NOT an estimate (suspended = 2)
        if ($suspended != 2) {
            //Update customer store account balance
            if ($customer_id > 0 && $balance) {
                $this->db->set('balance', 'balance+' . $balance, false);
                $this->db->where('person_id', $customer_id);
                if (!$this->db->update('customers')) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
            }
            //Update customer store account if payment made
            if ($customer_id > 0 && $store_account_payment_amount) {
                $this->db->set('balance', 'balance-' . $store_account_payment_amount, false);
                $this->db->where('person_id', $customer_id);
                if (!$this->db->update('customers')) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
            }
        }
        $previous_store_account_amount = 0;
        if ($sale_id !== FALSE) {
            $previous_store_account_amount = $this->get_store_account_payment_total($sale_id);
        }
        if ($sale_id) {
            //Delete previoulsy sale so we can overwrite data
            if (!$this->delete($sale_id, true)) {
                $this->db->query("ROLLBACK");
                $this->db->query('UNLOCK TABLES');
                return -1;
            }
            $this->db->where('sale_id', $sale_id);
            if (!$this->db->update('sales', $sales_data)) {
                $this->db->query("ROLLBACK");
                $this->db->query('UNLOCK TABLES');
                return -1;
            }
        } else {
            if (!$this->db->insert('sales', $sales_data)) {
                $this->db->query("ROLLBACK");
                $this->db->query('UNLOCK TABLES');
                return -1;
            }
            $sale_id = $this->db->insert_id();
        }
        //Only update store account payments if we are NOT an estimate (suspended = 2)
        if ($suspended != 2) {
            //insert store account transaction
            if ($customer_id > 0 && $balance) {
                $store_account_transaction = array('customer_id' => $customer_id, 'sale_id' => $sale_id, 'comment' => $comment, 'transaction_amount' => $balance - $previous_store_account_amount, 'balance' => $this->Customer->get_info($customer_id)->balance, 'date' => date('Y-m-d H:i:s'));
                if ($balance - $previous_store_account_amount) {
                    if (!$this->db->insert('store_accounts', $store_account_transaction)) {
                        $this->db->query("ROLLBACK");
                        $this->db->query('UNLOCK TABLES');
                        return -1;
                    }
                }
            } elseif ($customer_id > 0 && $previous_store_account_amount) {
                $store_account_transaction = array('customer_id' => $customer_id, 'sale_id' => $sale_id, 'comment' => $comment, 'transaction_amount' => -$previous_store_account_amount, 'balance' => $this->Customer->get_info($customer_id)->balance, 'date' => date('Y-m-d H:i:s'));
                if (!$this->db->insert('store_accounts', $store_account_transaction)) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
            }
            //insert store account payment transaction
            if ($customer_id > 0 && $store_account_payment) {
                $store_account_transaction = array('customer_id' => $customer_id, 'sale_id' => $sale_id, 'comment' => $comment, 'transaction_amount' => -$store_account_payment_amount, 'balance' => $this->Customer->get_info($customer_id)->balance, 'date' => date('Y-m-d H:i:s'));
                if (!$this->db->insert('store_accounts', $store_account_transaction)) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
            }
        }
        $total_giftcard_payments = 0;
        foreach ($payments as $payment_id => $payment) {
            //Only update giftcard payments if we are NOT an estimate (suspended = 2)
            if ($suspended != 2) {
                if (substr($payment['payment_type'], 0, strlen(lang('sales_giftcard'))) == lang('sales_giftcard')) {
                    /* We have a gift card and we have to deduct the used value from the total value of the card. */
                    $splitpayment = explode(':', $payment['payment_type']);
                    $cur_giftcard_value = $this->Giftcard->get_giftcard_value($splitpayment[1]);
                    $this->Giftcard->update_giftcard_value($splitpayment[1], $cur_giftcard_value - $payment['payment_amount']);
                    $total_giftcard_payments += $payment['payment_amount'];
                }
            }
            $sales_payments_data = array('sale_id' => $sale_id, 'payment_type' => $payment['payment_type'], 'payment_amount' => $payment['payment_amount'], 'payment_date' => $payment['payment_date'], 'truncated_card' => $payment['truncated_card'], 'card_issuer' => $payment['card_issuer']);
            if (!$this->db->insert('sales_payments', $sales_payments_data)) {
                $this->db->query("ROLLBACK");
                $this->db->query('UNLOCK TABLES');
                return -1;
            }
        }
        $has_added_giftcard_value_to_cost_price = $total_giftcard_payments > 0 ? false : true;
        $store_account_item_id = $this->Item->get_store_account_item_id();
        foreach ($items as $line => $item) {
            if (isset($item['item_id'])) {
                $cur_item_info = $this->Item->get_info($item['item_id']);
                $cur_item_location_info = $this->Item_location->get_info($item['item_id']);
                if ($item['item_id'] != $store_account_item_id) {
                    $cost_price = $cur_item_location_info && $cur_item_location_info->cost_price ? $cur_item_location_info->cost_price : $cur_item_info->cost_price;
                } else {
                    $cost_price = $item['price'];
                }
                if (!$this->config->item('disable_subtraction_of_giftcard_amount_from_sales')) {
                    //Add to the cost price if we are using a giftcard as we have already recorded profit for sale of giftcard
                    if (!$has_added_giftcard_value_to_cost_price) {
                        $cost_price += $total_giftcard_payments / $item['quantity'];
                        $has_added_giftcard_value_to_cost_price = true;
                    }
                }
                $reorder_level = $cur_item_location_info && $cur_item_location_info->reorder_level ? $cur_item_location_info->reorder_level : $cur_item_info->reorder_level;
                if ($cur_item_info->tax_included) {
                    $item['price'] = get_price_for_item_excluding_taxes($item['item_id'], $item['price']);
                }
                $sales_items_data = array('sale_id' => $sale_id, 'item_id' => $item['item_id'], 'line' => $item['line'], 'description' => $item['description'], 'serialnumber' => $item['serialnumber'], 'quantity_purchased' => $item['quantity'], 'discount_percent' => $item['discount'], 'item_cost_price' => to_currency_no_money($cost_price, 10), 'item_unit_price' => $item['price'], 'commission' => get_commission_for_item($item['item_id'], $item['price'], $item['quantity'], $item['discount']));
                if (!$this->db->insert('sales_items', $sales_items_data)) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
                //Only update giftcard payments if we are NOT an estimate (suspended = 2)
                if ($suspended != 2) {
                    //create giftcard from sales
                    if ($item['name'] == lang('sales_giftcard') && !$this->Giftcard->get_giftcard_id($item['description'])) {
                        $giftcard_data = array('giftcard_number' => $item['description'], 'value' => $item['price'], 'customer_id' => $customer_id > 0 ? $customer_id : null);
                        if (!$this->Giftcard->save($giftcard_data)) {
                            $this->db->query("ROLLBACK");
                            $this->db->query('UNLOCK TABLES');
                            return -1;
                        }
                    }
                }
                //Only do stock check + inventory update if we are NOT an estimate
                if ($suspended != 2) {
                    $stock_recorder_check = false;
                    $out_of_stock_check = false;
                    $email = false;
                    $message = '';
                    //checks if the quantity is greater than reorder level
                    if (!$cur_item_info->is_service && $cur_item_location_info->quantity > $reorder_level) {
                        $stock_recorder_check = true;
                    }
                    //checks if the quantity is greater than 0
                    if (!$cur_item_info->is_service && $cur_item_location_info->quantity > 0) {
                        $out_of_stock_check = true;
                    }
                    //Update stock quantity IF not a service
                    if (!$cur_item_info->is_service) {
                        $cur_item_location_info->quantity = $cur_item_location_info->quantity !== NULL ? $cur_item_location_info->quantity : 0;
                        if (!$this->Item_location->save_quantity($cur_item_location_info->quantity - $item['quantity'], $item['item_id'])) {
                            $this->db->query("ROLLBACK");
                            $this->db->query('UNLOCK TABLES');
                            return -1;
                        }
                    }
                    //Re-init $cur_item_location_info after updating quantity
                    $cur_item_location_info = $this->Item_location->get_info($item['item_id']);
                    //checks if the quantity is out of stock
                    if ($out_of_stock_check && $cur_item_location_info->quantity <= 0) {
                        $message = $cur_item_info->name . ' ' . lang('sales_is_out_stock') . ' ' . to_quantity($cur_item_location_info->quantity);
                        $email = true;
                    } else {
                        if ($stock_recorder_check && $cur_item_location_info->quantity <= $reorder_level) {
                            $message = $cur_item_info->name . ' ' . lang('sales_hits_reorder_level') . ' ' . to_quantity($cur_item_location_info->quantity);
                            $email = true;
                        }
                    }
                    //send email
                    if ($this->Location->get_info_for_key('receive_stock_alert') && $email) {
                        $this->load->library('email');
                        $config = array();
                        $config['mailtype'] = 'text';
                        $this->email->initialize($config);
                        $this->email->from($this->Location->get_info_for_key('email') ? $this->Location->get_info_for_key('email') : '*****@*****.**', $this->config->item('company'));
                        $this->email->to($this->Location->get_info_for_key('stock_alert_email') ? $this->Location->get_info_for_key('stock_alert_email') : $this->Location->get_info_for_key('email'));
                        $this->email->subject(lang('sales_stock_alert_item_name') . $this->Item->get_info($item['item_id'])->name);
                        $this->email->message($message);
                        $this->email->send();
                    }
                    if (!$cur_item_info->is_service) {
                        $qty_buy = -$item['quantity'];
                        $sale_remarks = $this->config->item('sale_prefix') . ' ' . $sale_id;
                        $inv_data = array('trans_date' => date('Y-m-d H:i:s'), 'trans_items' => $item['item_id'], 'trans_user' => $employee_id, 'trans_comment' => $sale_remarks, 'trans_inventory' => $qty_buy, 'location_id' => $this->Employee->get_logged_in_employee_current_location_id());
                        if (!$this->Inventory->insert($inv_data)) {
                            $this->db->query("ROLLBACK");
                            $this->db->query('UNLOCK TABLES');
                            return -1;
                        }
                    }
                }
            } else {
                $cur_item_kit_info = $this->Item_kit->get_info($item['item_kit_id']);
                $cur_item_kit_location_info = $this->Item_kit_location->get_info($item['item_kit_id']);
                $cost_price = $cur_item_kit_location_info && $cur_item_kit_location_info->cost_price ? $cur_item_kit_location_info->cost_price : $cur_item_kit_info->cost_price;
                if (!$this->config->item('disable_subtraction_of_giftcard_amount_from_sales')) {
                    //Add to the cost price if we are using a giftcard as we have already recorded profit for sale of giftcard
                    if (!$has_added_giftcard_value_to_cost_price) {
                        $cost_price += $total_giftcard_payments / $item['quantity'];
                        $has_added_giftcard_value_to_cost_price = true;
                    }
                }
                if ($cur_item_kit_info->tax_included) {
                    $item['price'] = get_price_for_item_kit_excluding_taxes($item['item_kit_id'], $item['price']);
                }
                $sales_item_kits_data = array('sale_id' => $sale_id, 'item_kit_id' => $item['item_kit_id'], 'line' => $item['line'], 'description' => $item['description'], 'quantity_purchased' => $item['quantity'], 'discount_percent' => $item['discount'], 'item_kit_cost_price' => $cost_price === NULL ? 0.0 : to_currency_no_money($cost_price, 10), 'item_kit_unit_price' => $item['price'], 'commission' => get_commission_for_item_kit($item['item_kit_id'], $item['price'], $item['quantity'], $item['discount']));
                if (!$this->db->insert('sales_item_kits', $sales_item_kits_data)) {
                    $this->db->query("ROLLBACK");
                    $this->db->query('UNLOCK TABLES');
                    return -1;
                }
                foreach ($this->Item_kit_items->get_info($item['item_kit_id']) as $item_kit_item) {
                    $cur_item_info = $this->Item->get_info($item_kit_item->item_id);
                    $cur_item_location_info = $this->Item_location->get_info($item_kit_item->item_id);
                    $reorder_level = $cur_item_location_info && $cur_item_location_info->reorder_level !== NULL ? $cur_item_location_info->reorder_level : $cur_item_info->reorder_level;
                    //Only do stock check + inventory update if we are NOT an estimate
                    if ($suspended != 2) {
                        $stock_recorder_check = false;
                        $out_of_stock_check = false;
                        $email = false;
                        $message = '';
                        //checks if the quantity is greater than reorder level
                        if (!$cur_item_info->is_service && $cur_item_location_info->quantity > $reorder_level) {
                            $stock_recorder_check = true;
                        }
                        //checks if the quantity is greater than 0
                        if (!$cur_item_info->is_service && $cur_item_location_info->quantity > 0) {
                            $out_of_stock_check = true;
                        }
                        //Update stock quantity IF not a service item and the quantity for item is NOT NULL
                        if (!$cur_item_info->is_service) {
                            $cur_item_location_info->quantity = $cur_item_location_info->quantity !== NULL ? $cur_item_location_info->quantity : 0;
                            if (!$this->Item_location->save_quantity($cur_item_location_info->quantity - $item['quantity'] * $item_kit_item->quantity, $item_kit_item->item_id)) {
                                $this->db->query("ROLLBACK");
                                $this->db->query('UNLOCK TABLES');
                                return -1;
                            }
                        }
                        //Re-init $cur_item_location_info after updating quantity
                        $cur_item_location_info = $this->Item_location->get_info($item_kit_item->item_id);
                        //checks if the quantity is out of stock
                        if ($out_of_stock_check && !$cur_item_info->is_service && $cur_item_location_info->quantity <= 0) {
                            $message = $cur_item_info->name . ' ' . lang('sales_is_out_stock') . ' ' . to_quantity($cur_item_location_info->quantity);
                            $email = true;
                        } else {
                            if ($stock_recorder_check && $cur_item_location_info->quantity <= $reorder_level) {
                                $message = $cur_item_info->name . ' ' . lang('sales_hits_reorder_level') . ' ' . to_quantity($cur_item_location_info->quantity);
                                $email = true;
                            }
                        }
                        //send email
                        if ($this->Location->get_info_for_key('receive_stock_alert') && $email) {
                            $this->load->library('email');
                            $config = array();
                            $config['mailtype'] = 'text';
                            $this->email->initialize($config);
                            $this->email->from($this->Location->get_info_for_key('email') ? $this->Location->get_info_for_key('email') : '*****@*****.**', $this->config->item('company'));
                            $this->email->to($this->Location->get_info_for_key('stock_alert_email') ? $this->Location->get_info_for_key('stock_alert_email') : $this->Location->get_info_for_key('email'));
                            $this->email->subject(lang('sales_stock_alert_item_name') . $cur_item_info->name);
                            $this->email->message($message);
                            $this->email->send();
                        }
                        if (!$cur_item_info->is_service) {
                            $qty_buy = -$item['quantity'] * $item_kit_item->quantity;
                            $sale_remarks = $this->config->item('sale_prefix') . ' ' . $sale_id;
                            $inv_data = array('trans_date' => date('Y-m-d H:i:s'), 'trans_items' => $item_kit_item->item_id, 'trans_user' => $employee_id, 'trans_comment' => $sale_remarks, 'trans_inventory' => $qty_buy, 'location_id' => $this->Employee->get_logged_in_employee_current_location_id());
                            if (!$this->Inventory->insert($inv_data)) {
                                $this->db->query("ROLLBACK");
                                $this->db->query('UNLOCK TABLES');
                                return -1;
                            }
                        }
                    }
                }
            }
            $customer = $this->Customer->get_info($customer_id);
            if ($customer_id == -1 or $customer->taxable) {
                if (isset($item['item_id'])) {
                    foreach ($this->Item_taxes_finder->get_info($item['item_id']) as $row) {
                        $tax_name = $row['percent'] . '% ' . $row['name'];
                        //Only save sale if the tax has NOT been deleted
                        if (!in_array($tax_name, $this->sale_lib->get_deleted_taxes())) {
                            $query_result = $this->db->insert('sales_items_taxes', array('sale_id' => $sale_id, 'item_id' => $item['item_id'], 'line' => $item['line'], 'name' => $row['name'], 'percent' => $row['percent'], 'cumulative' => $row['cumulative']));
                            if (!$query_result) {
                                $this->db->query("ROLLBACK");
                                $this->db->query('UNLOCK TABLES');
                                return -1;
                            }
                        }
                    }
                } else {
                    foreach ($this->Item_kit_taxes_finder->get_info($item['item_kit_id']) as $row) {
                        $tax_name = $row['percent'] . '% ' . $row['name'];
                        //Only save sale if the tax has NOT been deleted
                        if (!in_array($tax_name, $this->sale_lib->get_deleted_taxes())) {
                            $query_result = $this->db->insert('sales_item_kits_taxes', array('sale_id' => $sale_id, 'item_kit_id' => $item['item_kit_id'], 'line' => $item['line'], 'name' => $row['name'], 'percent' => $row['percent'], 'cumulative' => $row['cumulative']));
                            if (!$query_result) {
                                $this->db->query("ROLLBACK");
                                $this->db->query('UNLOCK TABLES');
                                return -1;
                            }
                        }
                    }
                }
            }
        }
        $this->db->query("COMMIT");
        $this->db->query('UNLOCK TABLES');
        return $sale_id;
    }
Example #3
0
 function _get_price_for_item_in_cart($item, $sale_id = FALSE)
 {
     $price_to_use = $item['price'];
     if (isset($item['item_id'])) {
         $item_info = $this->CI->Item->get_info($item['item_id']);
         if ($item_info->tax_included) {
             if ($sale_id) {
                 $price_to_use = get_price_for_item_excluding_taxes($item['line'], $item['price'], $sale_id);
             } else {
                 $price_to_use = get_price_for_item_excluding_taxes($item['item_id'], $item['price']);
             }
         }
     } elseif (isset($item['item_kit_id'])) {
         $item_kit_info = $this->CI->Item_kit->get_info($item['item_kit_id']);
         if ($item_kit_info->tax_included) {
             if ($sale_id) {
                 $price_to_use = get_price_for_item_kit_excluding_taxes($item['line'], $item['price'], $sale_id);
             } else {
                 $price_to_use = get_price_for_item_kit_excluding_taxes($item['item_kit_id'], $item['price']);
             }
         }
     }
     return $price_to_use;
 }
Example #4
0
 function complete()
 {
     $data['is_sale'] = TRUE;
     $data['cart'] = $this->sale_lib->get_cart();
     if (empty($data['cart'])) {
         redirect('sales');
     }
     if (!$this->_payments_cover_total()) {
         $this->_reload(array('error' => lang('sales_cannot_complete_sale_as_payments_do_not_cover_total')), false);
         return;
     }
     $tier_id = $this->sale_lib->get_selected_tier_id();
     $tier_info = $this->Tier->get_info($tier_id);
     $data['tier'] = $tier_info->name;
     $data['register_name'] = $this->Register->get_register_name($this->Employee->get_logged_in_employee_current_register_id());
     $data['subtotal'] = $this->sale_lib->get_subtotal();
     $data['taxes'] = $this->sale_lib->get_taxes();
     $data['total'] = $this->sale_lib->get_total();
     $data['receipt_title'] = lang('sales_receipt');
     $customer_id = $this->sale_lib->get_customer();
     $employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
     $sold_by_employee_id = $this->sale_lib->get_sold_by_employee_id();
     $data['comment'] = $this->sale_lib->get_comment();
     $data['show_comment_on_receipt'] = $this->sale_lib->get_comment_on_receipt();
     $emp_info = $this->Employee->get_info($employee_id);
     $sale_emp_info = $this->Employee->get_info($sold_by_employee_id);
     $data['payments'] = $this->sale_lib->get_payments();
     $data['is_sale_cash_payment'] = $this->sale_lib->is_sale_cash_payment();
     $data['amount_change'] = $this->sale_lib->get_amount_due() * -1;
     $data['balance'] = $this->sale_lib->get_payment_amount(lang('sales_store_account'));
     $data['employee'] = $emp_info->first_name . ' ' . $emp_info->last_name . ($sold_by_employee_id && $sold_by_employee_id != $employee_id ? '/' . $sale_emp_info->first_name . ' ' . $sale_emp_info->last_name : '');
     $data['ref_no'] = $this->session->userdata('ref_no') ? $this->session->userdata('ref_no') : '';
     $data['auth_code'] = $this->session->userdata('auth_code') ? $this->session->userdata('auth_code') : '';
     $data['discount_exists'] = $this->_does_discount_exists($data['cart']);
     $masked_account = $this->session->userdata('masked_account') ? $this->session->userdata('masked_account') : '';
     $card_issuer = $this->session->userdata('card_issuer') ? $this->session->userdata('card_issuer') : '';
     if ($masked_account) {
         $cc_payment_id = current($this->sale_lib->get_payment_ids(lang('sales_credit')));
         $cc_payment = $data['payments'][$cc_payment_id];
         $this->sale_lib->edit_payment($cc_payment_id, $cc_payment['payment_type'], $cc_payment['payment_amount'], $cc_payment['payment_date'], $masked_account, $card_issuer);
         //Make sure our payments has the latest change to masked_account
         $data['payments'] = $this->sale_lib->get_payments();
     }
     $data['change_sale_date'] = $this->sale_lib->get_change_sale_date_enable() ? $this->sale_lib->get_change_sale_date() : false;
     $old_date = $this->sale_lib->get_change_sale_id() ? $this->Sale->get_info($this->sale_lib->get_change_sale_id())->row_array() : false;
     $old_date = $old_date ? date(get_date_format() . ' ' . get_time_format(), strtotime($old_date['sale_time'])) : date(get_date_format() . ' ' . get_time_format());
     $data['transaction_time'] = $this->sale_lib->get_change_sale_date_enable() ? date(get_date_format() . ' ' . get_time_format(), strtotime($this->sale_lib->get_change_sale_date())) : $old_date;
     if ($customer_id != -1) {
         $cust_info = $this->Customer->get_info($customer_id);
         $data['customer'] = $cust_info->first_name . ' ' . $cust_info->last_name . ($cust_info->company_name == '' ? '' : ' - ' . $cust_info->company_name) . ($cust_info->account_number == '' ? '' : ' - ' . $cust_info->account_number);
         $data['customer_address_1'] = $cust_info->address_1;
         $data['customer_address_2'] = $cust_info->address_2;
         $data['customer_city'] = $cust_info->city;
         $data['customer_state'] = $cust_info->state;
         $data['customer_zip'] = $cust_info->zip;
         $data['customer_country'] = $cust_info->country;
         $data['customer_phone'] = $cust_info->phone_number;
         $data['customer_email'] = $cust_info->email;
     }
     $suspended_change_sale_id = $this->sale_lib->get_suspended_sale_id() ? $this->sale_lib->get_suspended_sale_id() : $this->sale_lib->get_change_sale_id();
     //If we have a previous sale make sure we get the ref_no unless we already have it set
     if ($suspended_change_sale_id && !$data['ref_no']) {
         $sale_info = $this->Sale->get_info($suspended_change_sale_id)->row_array();
         $data['ref_no'] = $sale_info['cc_ref_no'];
     }
     //If we have a previous sale make sure we get the auth_code unless we already have it set
     if ($suspended_change_sale_id && !$data['auth_code']) {
         $sale_info = $this->Sale->get_info($suspended_change_sale_id)->row_array();
         $data['auth_code'] = $sale_info['auth_code'];
     }
     //If we have a suspended sale, update the date for the sale
     if ($this->sale_lib->get_suspended_sale_id() && $this->config->item('change_sale_date_when_completing_suspended_sale')) {
         $data['change_sale_date'] = date('Y-m-d H:i:s');
     }
     $data['store_account_payment'] = $this->sale_lib->get_mode() == 'store_account_payment' ? 1 : 0;
     //SAVE sale to database
     $sale_id_raw = $this->Sale->save($data['cart'], $customer_id, $employee_id, $sold_by_employee_id, $data['comment'], $data['show_comment_on_receipt'], $data['payments'], $suspended_change_sale_id, 0, $data['ref_no'], $data['auth_code'], $data['change_sale_date'], $data['balance'], $data['store_account_payment']);
     $data['sale_id'] = $this->config->item('sale_prefix') . ' ' . $sale_id_raw;
     $data['sale_id_raw'] = $sale_id_raw;
     if ($customer_id != -1) {
         $cust_info = $this->Customer->get_info($customer_id);
         if ($cust_info->balance != 0) {
             $data['customer_balance_for_sale'] = $cust_info->balance;
         }
     }
     //If we don't have any taxes, run a check for items so we don't show the price including tax on receipt
     if (empty($data['taxes'])) {
         foreach (array_keys($data['cart']) as $key) {
             if (isset($data['cart'][$key]['item_id'])) {
                 $item_info = $this->Item->get_info($data['cart'][$key]['item_id']);
                 if ($item_info->tax_included) {
                     $price_to_use = get_price_for_item_excluding_taxes($data['cart'][$key]['item_id'], $data['cart'][$key]['price']);
                     $data['cart'][$key]['price'] = $price_to_use;
                 }
             } elseif (isset($data['cart'][$key]['item_kit_id'])) {
                 $item_info = $this->Item_kit->get_info($data['cart'][$key]['item_kit_id']);
                 if ($item_info->tax_included) {
                     $price_to_use = get_price_for_item_kit_excluding_taxes($data['cart'][$key]['item_kit_id'], $data['cart'][$key]['price']);
                     $data['cart'][$key]['price'] = $price_to_use;
                 }
             }
         }
     }
     if ($data['sale_id'] == $this->config->item('sale_prefix') . ' -1') {
         $data['error_message'] = '';
         if (is_sale_integrated_cc_processing()) {
             $data['error_message'] .= lang('sales_credit_card_transaction_completed_successfully') . '. ';
         }
         $data['error_message'] .= lang('sales_transaction_failed');
     } else {
         if ($this->sale_lib->get_email_receipt() && !empty($cust_info->email)) {
             $this->load->library('email');
             $config['mailtype'] = 'html';
             $this->email->initialize($config);
             $this->email->from($this->Location->get_info_for_key('email') ? $this->Location->get_info_for_key('email') : '*****@*****.**', $this->config->item('company'));
             $this->email->to($cust_info->email);
             $this->email->subject(lang('sales_receipt'));
             $this->email->message($this->load->view("sales/receipt_email", $data, true));
             $this->email->send();
         }
     }
     $this->load->view("sales/receipt", $data);
     $this->sale_lib->clear_all();
 }