<?php

class Invoice {

    /**
     * @var array Holds an array of data
     */
    protected $info = array();

    /**
     * @var bool Will be used to check whether the organization is added or not. TRUE when the organization is
     *      successfully created. Default value is FALSE
     */
    private $orgAdded = false;

    /**
     * @var obj Holds the database adapter object
     */
    public $db;
    private $year_id;
    private $year_id_actual;
    public $stop_transaction_start_end = false;
    public $permissions;

    /**
     * The constructor will create an instant of the chosen database adapter (MySQL, MySQLi, etc)
     * and saves it in a private variable $db as an object to be used throughout the class.
     *
     * @author  Taha Sayyad <info@trustotech.com>
     * @uses DBConnectorFactory::loadDriver() to load the database adapter
     */
    public function __construct() {
        $this->db = DBConnectorFactory::loadDriver();
        $this->year_id = Session::getCurrentYearID();
        $this->year_id_actual = Session::getCurrentYearIDActual();
        $this->permissions = new Permissions(smc_session()['user_logged_id']);
    }

    /**
     * The first thing to do is to set organization data using this method.<br .>
     * Before setting the organization data, the method will remove all unnecessary data from the array.
     * Next it will trim every single value.
     *
     * @author  Taha Sayyad <info@trustotech.com>
     * @param array $data Array of organization data
     */
    public function setdata(array $data) {
        $this->info = $data;
        return $this;
    }

    //    public function viewInvoice($IID) {
    //        $data = array();
    //        $query = $this->db->query('SELECT * from invoice_list_main WHERE Invoice_ID_Auto  = "' . $IID . '" and current_year_id = "' . $this->year_id . '"');
    //        while ($row = $this->db->assoc($query)) {
    //            $data[] = $row;
    //        }
    //
    //
    //        return $data;
    //    }
    public function getInvoicesDetails($IID) {
        $tax = 0;
        $totalVat = 0;
        $data = array();
        $query = $this->db->query('SELECT * FROM invoice_details WHERE Invoice_ID_Auto = "' . $IID . '" and current_year_id = "' . $this->year_id . '"');
        while ($row = $this->db->assoc($query)) {
            $tax += $row['Product_VAT'];
            $totalVat += $row['Product_VAT'];
            $data[] = $row;
        }
        $data['tax'] = $tax;
        $data['totalVAT'] = $totalVat;
        return $data;
    }

    public function insertSalesInvoice($depot_id = 1, $noupdate = null) {
        $error = token_unique::is_valid_token();
        if (!empty($error))
            return $error;
        $is_actual = isset($this->info['is_actual']) ? $this->info['is_actual'] : 0;
        $c_data = self::validateCustomerLimitBalance();
        $stop_query = $this->db->query('select stop_invoice from tbl_customers where Customer_ID = "' . $this->info['Customer_ID'] . '"');
        $stop_flag = $this->db->assoc($stop_query)['stop_invoice'];
//        $check = JV::checkCurrentYear($this->info['Invoice_Date'], $this->info['Invoice_Date'], $is_actual);
        $check = CommonFunctions::check_lock_data(['type' => 'invoice', 'start_date' => $this->info['Invoice_Date'], 'is_actual' => $is_actual]);
        if ($check !== '') {
            $error = array();
            $error[0] = $check;
            return $error;
        }
        $signature_image ='';
        if(isset($this->info['signature_image'])){
            $signature = $this->info['signature_image'];
            $signatureFileName = uniqid().'.png';
            $signature = str_replace('data:image/png;base64,', '', $signature);
            $signature = str_replace(' ', '+', $signature);
            $data = base64_decode($signature);
            $file = upload_path.'signatures/'.$signatureFileName;
            file_put_contents($file, $data);
            $signature_image = upload_url.'signatures/'.$signatureFileName;;

        }
//        if (!empty($this->info['unique_id']) && !empty(smc_session()['default_setting']['is_production'])) {
//            if (!isset(smc_session()['duplicate_check'][$this->info['unique_id']])) {
//                $error = array();
//                $error[0] = CommonLanguage::getMessage('duplicate_record');
//                return $error;
//            } else {
//                unset(smc_session()['duplicate_check'][$this->info['unique_id']]);
//            }
//        }
        $depot_id = $this->info['Depot_ID'];
        $web_api_inv_id = isset($this->info['web_api_inv_id']) ? $this->info['web_api_inv_id'] : 0;
        $web_api_user_id = isset($this->info['web_api_user_id']) ? $this->info['web_api_user_id'] : 0;
        $app_user_id = isset($this->info['app_user_id']) ? $this->info['app_user_id'] : 0;
        $invoice_app_id = isset($this->info['invoice_app_id']) ? $this->info['invoice_app_id'] : 0;
        $online_invoice_id = isset($this->info['online_invoice_id']) ? $this->info['online_invoice_id'] : 0;
        $invoice_type = (isset($this->info['invoice_type']) ? $this->info['invoice_type'] : (isset($this->info['pending_status']) && $this->info['pending_status'] == 3 ? 3 : 1));
        $is_committed = (isset($this->info['is_committed']) ? $this->info['is_committed'] : (isset($this->info['pending_status']) && $this->info['pending_status'] == 3 ? 0 : 1));
        $is_pos = isset($this->info['is_pos']) ? $this->info['is_pos'] : 0;
        $app_branch_id = isset($this->info['app_branch_id']) ? $this->info['app_branch_id'] : 0;
        $invoice_user_reference = !empty($this->info['invoice_user_reference']) ? $this->info['invoice_user_reference'] : NULL;
        $ticketing_id = !empty($this->info['ticketing_id']) ? $this->info['ticketing_id'] : NULL;
        $branch_id = isset($this->info['branch_id']) ? $this->info['branch_id'] : CommonBusiness::getBranchByDepot($depot_id);
        $this->info['branch_id'] = $branch_id;
        if (isset($this->info['invoice_prefix']))//sync from branch to server or from distribution app
            $invoice_prefix = $this->info['invoice_prefix'];
        else {
            //on server and invoice assigned to branch
            if ((smc_session()['default_setting']['sync_type'] == 1 && smc_session()['default_setting']['default_branch_id'] != $branch_id)) {
                $invoice_prefix = '';
            } else {//normal invoice or [sync from server to branch we already unset]
                $query_branch = $this->db->query('select branch_prefix from tbl_organization_branches where branch_id = "' . $branch_id . '"');
                $branch_prefix = $this->db->assoc($query_branch)['branch_prefix'];
                $invoice_prefix = smc_session()['user_accounts']['serial_prefix'] ? smc_session()['user_accounts']['serial_prefix'] : $branch_prefix;
            }
        }
        //customer name and code if ($Customer_ID == 0) "Customer_Name", Customer_Account, CurrencySymbole
        //$customerAccount = 53 name = customer ;,, currency symbol 
        //status:
        //0->unpaid
        //1->partially_paid
        //2->paid
        $this->info['currency_round'] = !empty($this->info['currency_round']) ? $this->info['currency_round'] : 0;
        $this->info['shipping_company_id'] = !empty($this->info['shipping_company_id']) ? $this->info['shipping_company_id'] : NULL;
        $sales_id = (smc_session()['default_setting']['sales_man_as_logged_user'] == 1 && empty($this->info['Sales_ID']) && !empty(smc_session()['user_details']['Employee_ID'])) ? smc_session()['user_details']['Employee_ID'] : (!empty($this->info['Sales_ID']) ? $this->info['Sales_ID'] : null);
        $Customer_ID = $this->info['Customer_ID'];

        if(smc_session()['default_setting']['enable_auto_increment_invoice_sync']){
            $inv_num = self::getMaxInvoice($invoice_prefix, $is_actual);
        }else{
            $inv_num = isset($this->info['Invoice_Number']) ? $this->info['Invoice_Number'] : ( (smc_session()['default_setting']['sync_type'] == 1 && smc_session()['default_setting']['default_branch_id'] != $branch_id) ? '' : self::getMaxInvoice($invoice_prefix, $is_actual));
        }
        
        if (isset($this->info['Invoice_Due_Date'])) {
            $Invoice_Due_Date = $this->info['Invoice_Due_Date'];
        } else {
            $Invoice_Due_Date = $this->info['Invoice_Date'];
        }
        $today = $this->info['Invoice_Date'];
        $Invoice_Sub_Total = $this->info['Invoice_Sub_Total'];
        $Invoice_Discount = $this->info['Invoice_Discount'];
        $Invoice_Net_Total = $this->info['Invoice_Net_Total'];
        //        $Invoice_Shipping       = $this->info['Invoice_Shipping'];
        $Invoice_VAT = $this->info['Invoice_VAT'];
        $this->info['vat1_total'] = !empty($this->info['vat1_total']) ? $this->info['vat1_total'] : $Invoice_VAT;
        $this->info['vat2_total'] = !empty($this->info['vat2_total']) ? $this->info['vat2_total'] : 0;
        $Invoice_Currency = $this->info['Invoice_Currency'];
        $sales_account = ($this->info['Account_Code'] == 0) ? smc_session()['user_accounts']['sales_account_id'] : $this->info['Account_Code'];
        if (!array_key_exists('Load_Order_ID', $this->info))
            $load_id = 0;
        else
            $load_id = $this->info['Load_Order_ID'];
        $mydate = date("Y-m-d H:i:s");
        //        $bon_num = self::getBonNum($this->info['Invoice_Date']);
        $this->info['Cash_Amount'] = !empty($this->info['Cash_Amount']) ? $this->info['Cash_Amount'] : 0;
        $this->info['Check_Amount'] = !empty($this->info['Check_Amount']) ? $this->info['Check_Amount'] : 0;
        $this->info['Card_Amount'] = !empty($this->info['Card_Amount']) ? $this->info['Card_Amount'] : 0;
        $this->info['Other_Amount'] = !empty($this->info['Other_Amount']) ? $this->info['Other_Amount'] : 0;
		$this->info['Other_Account'] = !empty($this->info['Other_Account']) ? $this->info['Other_Account'] : NULL;
        $paid = $this->info['Card_Amount'] + $this->info['Cash_Amount'] + $this->info['Check_Amount'] + $this->info['Other_Amount'];
        $payment_paid_amount = 0;
        $remaining = $Invoice_Net_Total + $this->info['shipping'] - $paid;
        $rem_cur = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($Invoice_Currency, $c_data['currency'], $remaining);
        if (smc_session()['default_setting']['generate_pay_rec_from_inv_pur'] == 1) {
            $paid = 0;
            $payment_paid_amount = $this->info['Card_Amount'] + $this->info['Cash_Amount'] + $this->info['Check_Amount'] + $this->info['Other_Amount'];
            $remaining = $Invoice_Net_Total + $this->info['shipping'];
        }
        if ($stop_flag == 1 && (($c_data['Balance'] + $rem_cur) > $c_data['Limit_Balance'])) {
            $error[0] = CommonLanguage::getMessage('customer_exceed_limtit');
            return $error;
        }
        $customer_account_arr = array();
        if (!empty($this->info['Customer_Account']) || !empty($this->info['Customer_Name'])) {
//            die('heyyy you');
            $customer_account_arr = Customer::getCustomerAccount($Customer_ID);
        }
        $customerAccount = !empty($this->info['Customer_Account']) ? $this->info['Customer_Account'] : $customer_account_arr['Account_ID'];
        //
        $status = 0;
        if (isset($this->info['Invoice_Status'])) {
            $status = $this->info['Invoice_Status'];
        } else {
            if (isset($this->info['pending_status']) && $this->info['pending_status'] == 3) {
                $status = 3;
            } else {
                //            if ($remaining > 0) {
                //                $status = 1;
                //            } else {
                //                $status = 2;
                //            }
                if ($remaining == 0) {
                    $status = 2;
                } elseif ($remaining < ($this->info['shipping'] + $Invoice_Net_Total)) {
                    $status = 1;
                }
            }
        }
        $rate = !empty($this->info['Invoice_Currency_Rate']) ? $this->info['Invoice_Currency_Rate'] : CurrencyFactory::getLastExRate($Invoice_Currency);
        $second_rate = !empty($this->info['second_currency_rate']) ? $this->info['second_currency_rate'] : CurrencyFactory::getSecondCurrencyLastExRate($this->info['Invoice_Currency']);
        //                 echo $rate.'==';
        //                 die();
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $this->info['Invoice_Description'] = !empty($this->info['Invoice_Description']) ? $this->info['Invoice_Description'] : '';
        $this->info['is_invoice_total_on_shipping'] = empty($this->info['is_invoice_total_on_shipping']) ? 0 : 1;
        $this->info['trans_on_change_status'] = empty($this->info['trans_on_change_status']) ? 0 : 1;
        $this->info['truck'] = isset($this->info['truck']) ? $this->info['truck'] : '';
        $year_id = $is_actual ? $this->year_id_actual : $this->year_id;
        $order_id = !empty($this->info['order_id']) ? $this->info['order_id'] : 0;
        $Bon_Number = isset($this->info['Bon_Number']) ? $this->info['Bon_Number'] : 0;
        $Inv_Type = isset($this->info['Inv_Type']) ? $this->info['Inv_Type'] : 2;
        $Delivery_Time = isset($this->info['Delivery_Time']) ? $this->info['Delivery_Time'] : '';
        $Is_Delivery = isset($this->info['Is_Delivery']) ? $this->info['Is_Delivery'] : 0;
        $Close_ID = isset($this->info['Close_ID']) ? $this->info['Close_ID'] : 0;
        $table_id = isset($this->info['table_id']) ? $this->info['table_id'] : 0;
        $Persons_Count = isset($this->info['Persons_Count']) ? $this->info['Persons_Count'] : 0;
        $pos_customer_id = isset($this->info['pos_customer_id']) ? $this->info['pos_customer_id'] : 0;
        $service_percant = isset($this->info['service_percant']) ? $this->info['service_percant'] : 0;
        $service_value = isset($this->info['service_value']) ? $this->info['service_value'] : 0;
        $is_app = isset($this->info['is_app']) ? $this->info['is_app'] : 0;
        $order_id_online = isset($this->info['order_id_online']) ? $this->info['order_id_online'] : 0;
        $address_id = isset($this->info['address_id']) ? $this->info['address_id'] : 0;
        $driver_id = isset($this->info['driver_id']) ? $this->info['driver_id'] : 0;
        $cash_amount = isset($this->info['cash_amount']) ? $this->info['cash_amount'] : 0;
        $date_created = isset($this->info['date_created']) ? $this->info['date_created'] : $mydate;
        $date_time = isset($this->info['date_time']) ? $this->info['date_time'] : $mydate;
        $this->info['created_logged_id'] = isset($this->info['created_logged_id']) ? $this->info['created_logged_id'] : $this->info['Logged_ID'];
        $posponted_type = !empty($this->info['posponted_type']) ? $this->info['posponted_type'] : 0;
        $postponed_date_time = !empty($this->info['postponed_date_time']) ? $this->info['postponed_date_time'] : NULL;
        $customer_name_alias = isset($this->info['customer_name_alias']) ? $this->info['customer_name_alias'] : '';
        $customer_address_alias = isset($this->info['customer_address_alias']) ? $this->info['customer_address_alias'] : '';
        $contra_id = !empty($this->info['contra_id']) ? $this->info['contra_id'] : null;
        $customer_branch_id = !empty($this->info['customer_branch_id']) ? $this->info['customer_branch_id'] : null;
        $current_invoice_type = !empty($this->info['current_invoice_type']) ? $this->info['current_invoice_type'] : null;
        $job_trans_type = smc_session()['default_setting']['job_transaction_type'];
        if (!empty($this->info['shipping_company_id'])) {
            $address_query = $this->db->query('select * from tbl_customer_shipping_address  where Customer_ID ="' . $Customer_ID . '" and is_default = 1');
            $row = $this->db->assoc($address_query);
            if (!empty($row['shipping_address_id']))
                $address_id = $row['shipping_address_id'];
        }
        $this->info['shipping_note'] = !empty($this->info['shipping_note']) ? $this->info['shipping_note'] : NULL;
        $ship_comp_acc_id = !empty($this->info['shipp_comp_acc_id']) ? $this->info['shipp_comp_acc_id'] : null;
        $data = [
            &$inv_num, &$Customer_ID, &$today, &$Invoice_Currency, &$Invoice_VAT, $this->info['vat1_total'], $this->info['vat2_total'], &$this->info['tax_amount'], &$Invoice_Sub_Total, &$Invoice_Discount,
            &$this->info['discount_amount'], &$Invoice_Net_Total, &$Invoice_Due_Date, &$date_created, &$date_time, &$this->info['Logged_ID'], &$this->info['created_logged_id'],
            &$load_id, &$year_id, &$this->info['Invoice_Description'], &$paid, &$status, &$depot_id,
            &$this->info['shipping'], &$rate, &$app_user_id, &$invoice_app_id, &$invoice_prefix, &$this->info['truck'],
            &$this->info['Class_ID'], &$branch_id, &$sales_id, &$sales_account, &$is_actual, &$this->info['job_id'], &$order_id,
            &$Bon_Number, &$Inv_Type, &$Delivery_Time, &$Is_Delivery, &$Close_ID, &$table_id,
            &$Persons_Count, &$pos_customer_id, &$service_percant,
            &$service_value, &$is_app, &$order_id_online, &$address_id, &$cash_amount, &$app_branch_id, &$second_rate, &$posponted_type, &$postponed_date_time,
            &$online_invoice_id, &$invoice_type, &$is_committed, &$is_pos,
            &$this->info['project_id'], &$this->info['shipping_company_id'], &$this->info['shipping_note'],
            &$invoice_user_reference, &$ship_comp_acc_id, &$this->info['is_invoice_total_on_shipping'], $this->info['trans_on_change_status'],
            &$web_api_inv_id, &$web_api_user_id, &$customer_name_alias, &$customer_address_alias,
            &$contra_id, &$this->info['currency_round'], &$customer_branch_id, &$current_invoice_type, &$ticketing_id, $this->info['po'], $this->info['project_name_inv'], $this->info['job_inv'], $this->info['project_code'], $this->info['our_ref'], $this->info['supply_date']
            , &$this->info['r_d_sph']
            , &$this->info['c_d_cyl']
            , &$this->info['c_d_ax']

            , &$this->info['c_d_sph']
            , &$this->info['l_d_cyl']
            , &$this->info['l_d_ax']

            , &$this->info['r_r_sph']
            , &$this->info['c_r_cyl']
            , &$this->info['c_r_ax']

            , &$this->info['c_r_sph']
            , &$this->info['l_r_cyl']
            , &$this->info['l_r_ax']
            ,$signature_image
            , &$this->info['cl_r_sph']
            , &$this->info['cl_r_cyl']
            , &$this->info['cl_r_axis']
            , &$this->info['cl_r_ipd']
            , &$this->info['cl_l_sph']
            , &$this->info['cl_l_cyl']
            , &$this->info['cl_l_axis']
            , &$this->info['cl_l_ipd']
            , &$driver_id
            , &$this->info['from_place']
            , &$this->info['to_place']

];
        $this->db->prepare_Stmt("INSERT INTO tbl_invoices (" . (!empty($this->info['fill_auto_id']) ? 'Invoice_ID_Auto,' : '') . "
            Invoice_ID,Customer_ID,Invoice_Date,Invoice_Currency,Invoice_VAT,vat1_total,vat2_total,tax_amount,Invoice_Sub_Total,Invoice_Discount,
            discount_amount,Invoice_Net_Total,Invoice_Due_Date,date_created,date_time,Logged_ID,created_logged_id,
            Load_ID,current_year_id,Invoice_Description,Invoice_Paid_Amount,Invoice_Status,Depot_ID,
            Invoice_Shipping,current_rate,app_user_id,invoice_app_id,invoice_prefix,truck,
            Class_ID,branch_id,Sales_ID,Account_ID,is_actual,job_id,order_id,Bon_Number,Inv_Type,Delivery_Time,
            Is_Delivery,Close_ID,table_id,Persons_Count,pos_customer_id,service_percant,
            service_value,is_app,order_id_online,address_id,cash_amount,app_branch_id,second_currency_rate,posponted_type,postponed_date_time,
            online_invoice_id,invoice_type,is_committed,is_pos,project_id,shipping_company_id,shipping_note,
            invoice_user_reference,ship_comp_acc_id,is_invoice_total_on_shipping,trans_on_change_status,web_api_inv_id,web_api_user_id,
            customer_name_alias,customer_address_alias,contra_id,currency_round,customer_branch_id,invoice_type_id,ticketing_id,po,project_name_inv,job_inv,project_code,our_ref,supply_date,r_d_sph,c_d_cyl,c_d_ax,c_d_sph,l_d_cyl,l_d_ax,r_r_sph,c_r_cyl,c_r_ax,c_r_sph,l_r_cyl,l_r_ax,signature_image,cl_r_sph,cl_r_cyl,cl_r_axis,cl_r_ipd,cl_l_sph,cl_l_cyl,cl_l_axis,cl_l_ipd,driver_id,from_place,to_place) 
            VALUES (" . (!empty($this->info['fill_auto_id']) ? intval($this->info['fill_auto_id']) . ',' : '') . "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", $data);
        //                 $error = $this->db->error();
        //                        echo"<pre>";
        //                        die(print_r($error));
        $Invoice_ID = $this->db->id();
        $prod_arr = array();
        $prod_ids_arr = array();

        $jv = JV::returnJV($is_actual);

        $customer_points_query = $this->db->query('select * from tbl_customers  where Customer_ID ="' . $Customer_ID .'" ');
            $row = $this->db->assoc($customer_points_query);
            if (empty($row['date_collected_point'])){
                $this->db->prepare_Stmt("update tbl_customers set date_collected_point = ? where Customer_ID = ?", [&$mydate, &$Customer_ID]);
            }

        $customerName = !empty($this->info['Customer_Name']) ? $this->info['Customer_Name'] : $customer_account_arr['Account_Name'];
        $curr_symbol = !empty($this->info['CurrencySymbole']) ? $this->info['CurrencySymbole'] : CurrencyFactory::getCurrencySymbol($Invoice_Currency);
        $ref_num = 'Inv.' . $invoice_prefix . $inv_num;
        $desc = !empty($this->info['Invoice_Description']) ? $this->info['Invoice_Description'] : ($customerName . ' bought products with ' . round(($Invoice_Net_Total + $this->info['shipping']), 2) . ' ' . $curr_symbol);
        $is_transaction_jv = ($Inv_Type == 2 && $status != 3);
        //echo $desc.'===';die();
        $expiry_valid_arr = array();
        $serial_valid_arr = array();
        $lot_valid_arr = array();
        $qty_valid_arr = array();
        $depot_arr = array();
//        echo"<pre>";die(print_r($this->info['Products']));
        foreach ($this->info['Products'] as $item) {

            $prod_ids_arr[] = $item['Product_ID'];
            //            $prod_arr
            $ProductID = $item['Product_ID'];
            $ProductQuantityRate = Product::getConvertedQuantity($item['UOM_ID'], 1, $item['Product_ID']);
            $ProductQuantity = $ProductQuantityRate * $item['Item_Quantity'];
            $ProductDiscount = $item['Item_Discount'];
            $ProductNetPrice = $item['Item_Price'];
            $item["vat2_percent"] = !empty($item["vat2_percent"]) ? $item["vat2_percent"] : 0;
            $item["vat2_amount"] = !empty($item["vat2_amount"]) ? $item["vat2_amount"] : 0;
            $Product_Total_Price = $item['Product_Total_Price'];
            $Product_Description = isset($item['product_description']) ? $item['product_description'] : '';
            $purchase_detail_id = !empty($item['purchase_detail_id']) ? $item['purchase_detail_id'] : null;
            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => ($Product_Total_Price),
                "description" => $Product_Description, "vat_amount" => ($item['vat_val'] + $item['vat2_amount']));
            $expiry_date = !empty($item['expiry_date']) ? $item['expiry_date'] : null;
            $depot_detail_id = !empty($item['depot_id']) ? $item['depot_id'] : $depot_id;
            $vehicle_id = !empty($item['vehicle_id']) ? $item['vehicle_id'] : null;
            $employee_id = !empty($item['employee_id']) ? $item['employee_id'] : null;
            $commission = !empty($item['commission']) ? $item['commission'] : 0;
            $lot_nb = !empty($item['lot_nb']) ? $item['lot_nb'] : '';
            $serial_nb = !empty($item['serial_nb']) ? $item['serial_nb'] : '';
            $unit_cost = !empty($item['delivery_cost']) ? $item['delivery_cost'] : 0;
            $item['is_service'] = !empty($item['is_service']) ? $item['is_service'] : 0;
            if (empty($depot_arr[$depot_detail_id]))
                $depot_arr[$depot_detail_id] = $depot_detail_id;
            if (empty($item['delivery_id'])) {
                $costdata = [
                    "Product_ID" => $ProductID,
                    "Quantity" => $ProductQuantity,
                    "Unit_Cost" => "",
                    "unit_price" => $ProductNetPrice,
                    "Currency_ID" => $Invoice_Currency,
                    "date_time" => $date_created,
                    "date_time_now" => $date_created,
                    "current_rate" => $rate,
                    "depot_id" => $depot_detail_id,
                    "trans_date" => $today,
                    "current_quantity" => $item['Item_Quantity'],
                    "uom_id" => $item['UOM_ID'],
                    "is_actual" => $is_actual,
                    "expiry_date" => $expiry_date,
                    "lot_nb" => $lot_nb,
                    "serial_nb" => $serial_nb,
                    "main_id" => $Invoice_ID,
                    "is_service" => $item['is_service'],
                    "main_nb" => $invoice_prefix . $inv_num,
                    "customer_id" => $Customer_ID
                ];
                //            $cost = CommonBusiness::addCostByType($costdata, "add_invoice");
                //            $unit_cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $Invoice_Currency, $cost);
                //                if (is_null($noupdate)) {
                //                    $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $ProductID . '"');
                //
                //                    $count_row = $this->db->rowsno($link_query);
                //                    if ($count_row == 0) {
                //                        $cost = self::updateLinkQuantities($costdata, "add_invoice", '-');
                //                        $unit_cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                //                    } else {
                //                        while ($link = $this->db->assoc($link_query)) {
                //                            $link_qty = $link['quantity'] * $ProductQuantity;
                //                            $costdata["Quantity"] = $link_qty;
                //                            $costdata["current_quantity"] = $link['current_quantity'] * $ProductQuantity;
                //                            $costdata["Product_ID"] = $link['sub_product_id'];
                //                            $costdata["uom_id"] = $link['UOM_ID'];
                //                            $cost = self::updateLinkQuantities($costdata, "add_invoice", $link['operation']);
                //                            echo $cost.='==';
                //                            $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                //                        }
                //                    }
                //                }
                $option_arr = !empty($item['options_arr']) ? json_decode($item['options_arr'], true) : array();
                $product_links = CommonBusiness::get_product_links($ProductID, $item['UOM_ID'], $ProductQuantity, $item['Item_Quantity'], '-', 0, $option_arr);
                                                            //    echo"<pre>";die(print_r($product_links));
                $is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $item['Product_ID'] . '" ');
                $is_rate_row = $this->db->assoc($is_rate_query); 
                $is_rate_type_one = $is_rate_row['is_rate_type_one'];
                $is_rate_type_two = $is_rate_row['is_rate_type_two'];
                $rate_type_one = smc_session()['default_setting']['rate_type_one'];
                $rate_type_two = smc_session()['default_setting']['rate_type_two'];

                $effect_qty_link_product  = $is_rate_row['effect_qty_link_product'];

        


                foreach ($product_links as $link) {
                    $link_is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $link['Product_ID'] . '" ');
                    $link_is_rate_row = $this->db->assoc($link_is_rate_query); 
                    $link_is_rate_type_one = $link_is_rate_row['is_rate_type_one'];
                    $link_is_rate_type_two = $link_is_rate_row['is_rate_type_two'];
    
                    $costdata["Quantity"] = $link['Quantity'];
                    $costdata["current_quantity"] = $link['current_quantity'];

                    if($is_rate_type_one == 1 && $link_is_rate_type_one == 1 && $rate_type_one > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_one)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"] ;
                    }

                    if($is_rate_type_two == 1 && $link_is_rate_type_two == 1  && $rate_type_two > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_two)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"] ;
                    }

                    if($effect_qty_link_product == 1){
                        $costdata["Quantity"] = $item['qty_link'];
                        $costdata["current_quantity"] = $item['qty_link'];
                    }

                    $costdata["Product_ID"] = $link['Product_ID'];
                    $costdata["uom_id"] = $link['uom_id'];
                    $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                    $cost = self::updateLinkQuantities($costdata, "add_invoice", $link['operation']) * ($link['Quantity'] / ($ProductQuantityRate * $item['Item_Quantity']));
                    //                                        echo $cost.='==';
                    $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);

                    if (!empty($expiry_date) && !empty(smc_session()['default_setting']['activate_expiry_qty_exist']) && empty($invoice_app_id)) {
                        $expiry_valid_arr['expiry'][] = $expiry_date;
                        if (!isset($expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date]))
                            $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] = 0;
                        $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] += $link['Quantity'];
                    }
                    if (!empty($serial_nb) && !empty(smc_session()['default_setting']['activate_serial_qty_exist']) && empty($invoice_app_id)) {
                        $serial_valid_arr['serial'][] = $serial_nb;
                        if (!isset($serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb]))
                            $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] = 0;
                        $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] += $link['Quantity'];
                    }
                    if (!empty($lot_nb) && !empty(smc_session()['default_setting']['activate_lot_qty_exist']) && empty($invoice_app_id)) {
                        $lot_valid_arr['lot'][] = $lot_nb;
                        if (!isset($lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb]))
                            $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] = 0;
                        $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] += $link['Quantity'];
                    }
                    if (!empty($link['Quantity']) && empty(smc_session()['default_setting']['negative_sales']) && empty($invoice_app_id)) {
                        if (!isset($qty_valid_arr[$link['Product_ID']][$depot_detail_id]))
                            $qty_valid_arr[$link['Product_ID']][$depot_detail_id] = 0;
                        $qty_valid_arr[$link['Product_ID']][$depot_detail_id] += $link['Quantity'];
                    }
                }
            }
            
            //            die();
            //            echo $unit_cost.'===';die();
            $item['delivery_id'] = !empty($item['delivery_id']) ? $item['delivery_id'] : null;
            $total_tax = empty($item['total_tax']) ? 0 : $item['total_tax'];
            $prod_disc_amt = !isset($item['Discount_Amount']) ? ($item['Item_Quantity'] * $item['Item_Price'] * $item['Item_Discount'] / 100) : $item['Discount_Amount'];
            $item['subscription_fees_detail_id'] = empty($item['subscription_fees_detail_id']) ? NULL : $item['subscription_fees_detail_id'];
            $prod = [&$Invoice_ID, &$ProductID, &$ProductDiscount, &$prod_disc_amt, &$ProductNetPrice, &$ProductQuantity,
                &$Product_Total_Price, &$unit_cost, &$item['Item_Quantity'], &$item['UOM_ID'], &$item['vat_percent'],
                &$item['vat_val'], $item['vat2_percent'], $item['vat2_amount'], &$Product_Description, &$purchase_detail_id, &$expiry_date, &$depot_detail_id,
                &$vehicle_id, &$employee_id, &$commission, &$total_tax, &$lot_nb, &$serial_nb, &$item['delivery_id'], &$mydate, &$item['subscription_fees_detail_id'], &$item['from_time'], &$item['to_time'], &$item['modify_date']
                , &$item['item_driver_id']
                , &$item['n_total']
                , &$item['n_width']
                , &$item['n_height']
                , &$item['qty_link']
                , &$item['is_collected_points']
            
            ];
            $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (
                Invoice_ID_Auto,Product_ID,Product_Discount,Discount_Amount,Product_Net_Price,Product_Quantity,
                Product_Total_Price,unit_cost,Item_Quantity_Current,UOM_ID,vat_percent,
                vat_amount,vat2_percent,vat2_amount,product_description,purchase_detail_id,expiry_date,depot_id,vehicle_id,
                employee_id,commission,total_tax,lot_nb,serial_nb,Delivery_Report_ID,date_created,subscription_fees_detail_id,from_time,to_time,modify_date
                ,driver_id
                ,n_total
                ,n_width
                ,n_height
                ,qty_link
                ,is_collected_points
                
                ) 
                VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", $prod);
            
            $is_collect_points_query = $this->db->query('select * from tbl_invoice_products_details where Invoice_ID_Auto ="' . $Invoice_ID .'" and Product_ID ="' . $ProductID .'" ');
                $collect_points_row = $this->db->assoc($is_collect_points_query);
                $is_collect_points = $collect_points_row['is_collected_points'];

            $customer_points_query2 = $this->db->query('select * from tbl_customers where Customer_ID ="' . $Customer_ID .'" ');
                $customer_points_row = $this->db->assoc($customer_points_query2);
                $cust_points = $customer_points_row['collected_points'];
            $product_points_query = $this->db->query('select * from tbl_stock_products where Product_ID ="' . $ProductID .'" ');
                $product_points_row = $this->db->assoc($product_points_query);
            if($is_collect_points == 0){
                    $positive_points = $product_points_row['positive_points'] * $item['Item_Quantity'];
                $cust_positive_points = $cust_points + $positive_points;
                $this->db->prepare_Stmt("update tbl_customers set collected_points = ? where Customer_ID = ?", [&$cust_positive_points, &$Customer_ID]);
            }else{
                   $negative_points = $product_points_row['negative_points'] * $item['Item_Quantity'];
                if($cust_points >= $negative_points){
                    $cust_negative_points = $cust_points - $negative_points;
                    $this->db->prepare_Stmt("update tbl_customers set collected_points = ? where Customer_ID = ?", [&$cust_negative_points, &$Customer_ID]);
                  //  $this->db->prepare_Stmt('update tbl_invoice_products_details set Product_Discount = 100, Product_Total_Price = 0, Discount_Amount ="' . $ProductNetPrice .'"  where Invoice_ID_Auto ="' . $Invoice_ID .'" and Product_ID ="' . $ProductID .'"');
                }else{
                    $error[0] = CommonLanguage::getMessage('The points you have are not enough to get this product !');
                    return $error;
                }
            }

            $new_entry_id = $this->db->id();
            if (!empty($item['add_ons'])) {
                $add_on_data = array('id' => $new_entry_id, 'add_ons' => $item['add_ons']);
                Invoicepos::addInvDetailAddOns($add_on_data);
            }
            if (array_key_exists('options_arr', $item)) {
                $arr = array();
                $arr['options_arr'] = $item['options_arr'];
                $arr['id'] = $new_entry_id;
                Invoicepos::add_invoice_detail_options($arr);
            }
            if (!empty($item['criteria_details'])) {
                $criteria_details = $item['criteria_details'];
                foreach ($criteria_details as $details) {
                    $this->db->prepare_Stmt("INSERT INTO
                                        tbl_invoice_product_criteria 
                                        (Entery_ID,Quantity,criteria_detail_id,criteria_price,criteria_note)
                                        VALUES
                                        (?,?,?,?,?)
                    ", [&$new_entry_id, &$details['Quantity'], &$details['criteria_detail_id'],
                        &$details['criteria_price'], &$details['criteria_note']]);
                }
            }

            if ($is_transaction_jv && !empty($item['employee_id']) && !empty($item['commission'])) {
                $employee_acc_arr = Employee::viewEmployeeAccount($item['employee_id']);
                $dat_31 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $employee_acc_arr['exp'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $item['commission'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_31, $is_actual);
                $dat_32 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $employee_acc_arr['inc'],
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $item['commission'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_32, $is_actual);
            }
        }
        if (!empty($expiry_valid_arr)) {
            $expiry_valid = CommonBusiness::validate_expiry_qty_exist($expiry_valid_arr, $depot_arr);
            if (!empty($expiry_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['expiry_error', $expiry_valid];
            }
        }
        if (!empty($lot_valid_arr)) {
            $lot_valid = CommonBusiness::validate_lot_qty_exist($lot_valid_arr, $depot_arr);
            if (!empty($lot_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['lot_error', $lot_valid];
            }
        }
        if (!empty($serial_valid_arr)) {
            $serial_valid = CommonBusiness::validate_serial_qty_exist($serial_valid_arr, $depot_arr);
            if (!empty($serial_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['serial_error', $serial_valid];
            }
        }
            // echo"<pre>";die(print_r($qty_valid_arr));
        if (!empty($qty_valid_arr)) {
            $qty_valid = CommonBusiness::validate_product_qty_exist($qty_valid_arr, $depot_arr);
            if (!empty($qty_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['qty_error', $qty_valid];
            }
        }
        if (!empty($this->info['subscription_fees_id']))
            $this->db->prepare_Stmt("update  tbl_invoices set subscription_fees_id = ? where Invoice_ID_Auto = ?", [&$this->info['subscription_fees_id'], &$Invoice_ID]);
        if (!empty($this->info['order_id']))
            $this->db->prepare_Stmt("update  tbl_purchase_order set is_converted = 1 where Order_ID = ?", [&$this->info['order_id']]);
        
        
        if ($is_transaction_jv) {
            $prod_str =implode( ',',$prod_ids_arr);
            $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $sales_account, $Invoice_Discount, $this->info['shipping_account'], $this->info['shipping'], $this->info['tax_amount']);
            //        $c_account = JV::getAccountCodeByID($customerAccount);
            $vat_account = Customer::returnCustomerVATAccount($Customer_ID)['Account_ID'];
            $amount_novat = $Invoice_Net_Total - $Invoice_VAT - $this->info['shipping'];
            //returnExchangeRate
            $ref_num = 'Inv.' . $invoice_prefix . $inv_num;
                //    echo"<pre>";print_r($prod_trans_arr);
            foreach ($prod_trans_arr as $trans) {
                //            $trans_desc = $trans[]
                if (isset($trans['main'])) {
                    $trans_main = $trans['main'];
                    $data_trans = ["JV_ID" => $jv,
                        "Transaction_Reference" => (empty($trans_main['ref']) ? 'inv' : $trans_main['ref']),
                        "Transaction_Account" => $trans_main['trans_account'],
                        "Transaction_Type" => "Credit",
                        "Transaction_Amount" => $trans_main['trans_amount'],
                        "Transaction_Date" => $today,
                        "Currency_ID" => $Invoice_Currency,
                        "Logged_ID" => $this->info['Logged_ID'],
                        "created_logged_id" => $this->info['created_logged_id'],
                        "Transaction_Description" => (empty($trans_main['trans_desc']) ? $desc : $trans_main['trans_desc']),
                        "date_created" => $date_created,
                        "date_time" => $date_time,
                        "Current_Ex_Rate" => $rate,
                        "second_currency_rate" => $second_rate,
                        "main_id" => $Invoice_ID,
                        "main_type" => "inv",
                        "branch_id" => $branch_id,
                        "due_date" => $Invoice_Due_Date,
                        "subtype" => "inv",
                        "main_nb" => $inv_num,
                        "prefix" => $invoice_prefix,
                        "user_ref" => $invoice_user_reference,
                        "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                        "project_id" => $this->info['project_id'],
                        "salesman_id" => $sales_id,
                    ];
                    JV::addTransaction($data_trans, $is_actual);
                }
                if (isset($trans['person'])) {
                    $trans_person = $trans['person'];
                    $cust_amount = smc_session()['default_setting']['merge_cust_supp_accounts'] == 1 ? ($trans_person['trans_amount'] + $this->info['currency_round'] ) : $trans_person['trans_amount'];
                    $data_trans = ["JV_ID" => $jv,
                        "Transaction_Reference" => $ref_num,
                        "Transaction_Account" => $customerAccount,
                        "Transaction_Type" => "Debit",
                        "Transaction_Amount" => $cust_amount,
                        "Transaction_Date" => $today,
                        "Currency_ID" => $Invoice_Currency,
                        "Logged_ID" => $this->info['Logged_ID'],
                        "created_logged_id" => $this->info['created_logged_id'],
                        "Transaction_Description" => (empty($trans_person['trans_desc']) ? $desc : $trans_person['trans_desc']) . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                        "date_created" => $date_created,
                        "date_time" => $date_time,
                        "Current_Ex_Rate" => $rate,
                        "second_currency_rate" => $second_rate,
                        "main_id" => $Invoice_ID,
                        "main_type" => "inv",
                        "branch_id" => $branch_id,
                        "due_date" => $Invoice_Due_Date,
                        "main_nb" => $inv_num,
                        "prefix" => $invoice_prefix,
                        "user_ref" => $invoice_user_reference,
                        "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                        "project_id" => $this->info['project_id'],
                        "salesman_id" => $sales_id,
                        "pos_customer_id" => $pos_customer_id
                    ];
                    JV::addTransaction($data_trans, $is_actual);
                }
            }
            if (smc_session()['default_setting']['merge_cust_supp_accounts'] == 0) {
                $trans_type = $this->info['currency_round'] < 0 ? 'Credit' : 'Debit';
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customerAccount,
                    "Transaction_Type" => $trans_type,
                    "Transaction_Amount" => abs($this->info['currency_round']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => $pos_customer_id
                ];
                JV::addTransaction($data_trans, $is_actual);
            }
            $discount_account = !empty(smc_session()['user_accounts']['discount_account']) ? smc_session()['user_accounts']['discount_account'] : $sales_account;
            $trans_disc_type = $this->info['currency_round'] > 0 ? 'Credit' : 'Debit';
            $data_disc = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $discount_account,
                "Transaction_Type" => $trans_disc_type,
                "Transaction_Amount" => abs($this->info['currency_round']),
                "Transaction_Date" => $today,
                "Currency_ID" => $Invoice_Currency,
                "Logged_ID" => $this->info['Logged_ID'],
                "created_logged_id" => $this->info['created_logged_id'],
                "Transaction_Description" => $desc,
                "date_created" => $date_created,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate,
                "main_id" => $Invoice_ID,
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $Invoice_Due_Date,
                "main_nb" => $inv_num,
                "prefix" => $invoice_prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id,
            ];
            JV::addTransaction($data_disc, $is_actual);
            
            $Invoice_Currency = &$this->info['Invoice_Currency'];
            $second_rate2 = $this->info['second_rate'];
            $lebanon_vat_amount=smc_session()['default_setting']['lebanon_vat_amount'];
            if($Invoice_Currency == '144'){
                $second_rate2 = $lebanon_vat_amount;
            }
            
            $dat_3 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => (!empty(smc_session()['account_setting']['customer_fixed_vat_acc_id']) ? smc_session()['account_setting']['customer_fixed_vat_acc_id'] : $vat_account),
                "Transaction_Type" => "Credit",
                "Transaction_Amount" => $this->info['vat1_total'],
                "Transaction_Date" => $today,
                "Currency_ID" => $Invoice_Currency,
                "Logged_ID" => $this->info['Logged_ID'],
                "created_logged_id" => $this->info['created_logged_id'],
                "Transaction_Description" => $desc,
                "date_created" => $date_created,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate2,
                "main_id" => $Invoice_ID,
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $Invoice_Due_Date,
                "main_nb" => $inv_num,
                "prefix" => $invoice_prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id,
                "subtype" => "vat1"
            ];
            JV::addTransaction($dat_3, $is_actual);
            $dat_3 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => (!empty(smc_session()['account_setting']['customer_fixed_vat_acc_id']) ? smc_session()['account_setting']['customer_fixed_vat_acc_id'] : $vat_account),
                "Transaction_Type" => "Credit",
                "Transaction_Amount" => $this->info['vat2_total'],
                "Transaction_Date" => $today,
                "Currency_ID" => $Invoice_Currency,
                "Logged_ID" => $this->info['Logged_ID'],
                "created_logged_id" => $this->info['created_logged_id'],
                "Transaction_Description" => $desc,
                "date_created" => $date_created,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate,
                "main_id" => $Invoice_ID,
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $Invoice_Due_Date,
                "main_nb" => $inv_num,
                "prefix" => $invoice_prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id,
                "subtype" => "vat2"
            ];
            JV::addTransaction($dat_3, $is_actual);
                //        $dat_10 = ["JV_ID" => $jv,
                //            "Transaction_Reference" => 'ship',
                //            "Transaction_Account" => $this->info['shipping_account'],
                //            "Transaction_Type" => "Credit",
                //            "Transaction_Amount" => $this->info['shipping'],
                //            "Transaction_Date" => $today,
                //            "Currency_ID" => $Invoice_Currency,
                //            "Logged_ID" => $this->info['Logged_ID'],
                //            "Transaction_Description" => $desc,
                //            "Current_Ex_Rate" => $rate,
                //            "main_id" => $Invoice_ID,
                //            "main_type" => "inv",
                //            "branch_id" => $branch_id,
                //            "due_date" => $Invoice_Due_Date,
                //            "subtype" => "ship",
                //            "main_nb" => $inv_num,
                //            "prefix" => $invoice_prefix,
                //            "job_id" => $this->info['job_id']
                //        ];
                //        JV::addTransaction($dat_10, $is_actual);
            if ($this->info['is_invoice_total_on_shipping'] == 1) {
                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customerAccount,
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => ($Invoice_Net_Total + $this->info['shipping']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => $pos_customer_id
                ];
                JV::addTransaction($dat_122, $is_actual);
                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $ship_comp_acc_id,
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $Invoice_Net_Total,
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_122, $is_actual);
                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $this->info['shipping_account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['shipping'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_122, $is_actual);
            }
            if (smc_session()['default_setting']['generate_pay_rec_from_inv_pur'] == 0) {
                //customer transaction
                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => ($this->info['is_invoice_total_on_shipping'] == 0 ? $customerAccount : $ship_comp_acc_id),
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $Invoice_Net_Total - $remaining,
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc . (!empty($this->info['customer_branch_name']) && $this->info['is_invoice_total_on_shipping'] == 0 ? (' - ' . $this->info['customer_branch_name']) : ''),
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => ($this->info['is_invoice_total_on_shipping'] == 0 ? $pos_customer_id : 0)
                ];
                JV::addTransaction($dat_122, $is_actual);
                $dat_4 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'credit',
                    "Transaction_Account" => $this->info['Card_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Card_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "subtype" => "credit",
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => (!empty($this->info['card_user_ref']) ? $this->info['card_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_4, $is_actual);
                $dat_5 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'cash',
                    "Transaction_Account" => $this->info['Cash_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Cash_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "subtype" => "cash",
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => (!empty($this->info['cash_user_ref']) ? $this->info['cash_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_5, $is_actual);
                $dat_5 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'other',
                    "Transaction_Account" => $this->info['Other_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Other_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $Invoice_Due_Date,
                    "subtype" => "other",
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => (!empty($this->info['other_user_ref']) ? $this->info['other_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_5, $is_actual);
                $dat_6 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'check',
                    "Transaction_Account" => $this->info['Check_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Check_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $Invoice_Currency,
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => $desc,
                    "date_created" => $date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $Invoice_ID,
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => (!empty($this->info['check_due_date']) ? $this->info['check_due_date'] : $Invoice_Due_Date),
                    "value_date" => (empty($this->info['value_date']) ? '' : $this->info['value_date']),
                    "check_nb" => (empty($this->info['Check_Num']) ? '' : $this->info['Check_Num']),
                    "subtype" => "check",
                    "main_nb" => $inv_num,
                    "prefix" => $invoice_prefix,
                    "user_ref" => (!empty($this->info['check_user_ref']) ? $this->info['check_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                ];
                JV::addTransaction($dat_6, $is_actual);
            } else {
                if ($this->info['Cash_Amount'] > 0 || $this->info['Card_Amount'] > 0 || $this->info['Check_Amount'] > 0) {
                    $pay_data = array();
                    $pay_data['Payment_Date'] = $this->info['Invoice_Date'];
                    $pay_data['Status_ID'] = $is_actual;
                    $pay_data['branch_id'] = $branch_id;
                    $pay_data['payment_prefix'] = $invoice_prefix;
                    $pay_data['IsReceipt'] = 1;
                    $pay_data['Currency_Rate'] = $rate;
                    $pay_data['Currency_ID'] = $Invoice_Currency;
                    $pay_data['date_time'] = $date_time;
                    $pay_data['date_created'] = $date_created;
                    $pay_data['Logged_ID'] = $this->info['Logged_ID'];
                    $pay_data['created_logged_id'] = $this->info['created_logged_id'];
                    $pay_data['Account_Code'] = $customerAccount;
                    $pay_data['job_id'] = $this->info['job_id'];
                    $pay_data['project_id'] = $this->info['project_id'];
                    $pay_data['total_payment'] = $payment_paid_amount;
                    $pay_data['salesman_id'] = $sales_id;
                    $pay_data['payment'] = array();
                    if ($this->info['Card_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Card_Account'],
                            'Payment_Amount' => $this->info['Card_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => '',
                            'Check_Date' => '',
                            'value_date' => '',
                            'user_ref' => (empty($this->info['card_user_ref']) ? '' : $this->info['card_user_ref']),
                        );
                    }
                    if ($this->info['Cash_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Cash_Account'],
                            'Payment_Amount' => $this->info['Cash_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => '',
                            'Check_Date' => '',
                            'value_date' => '',
                            'user_ref' => (empty($this->info['cash_user_ref']) ? '' : $this->info['cash_user_ref']),
                        );
                    }
                    if ($this->info['Check_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Check_Account'],
                            'Payment_Amount' => $this->info['Check_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => (empty($this->info['Check_Num']) ? '' : $this->info['Check_Num']),
                            'Check_Date' => (!empty($this->info['check_due_date']) ? $this->info['check_due_date'] : $Invoice_Due_Date),
                            'value_date' => (empty($this->info['value_date']) ? '' : $this->info['value_date']),
                            'user_ref' => (empty($this->info['check_user_ref']) ? '' : $this->info['check_user_ref']),
                        );
                    }
                    $pay_data['close_arr'][] = array(
                        'inv_id' => $Invoice_ID,
                        'inv_amount' => $payment_paid_amount,
                        'inv_currency' => $Invoice_Currency
                    );
                    // print_r($pay_data);exit;
                    $payment = new Payment();
                    $payment->stop_transaction_start_end = true;
                    $payment->setData($pay_data)->create();
                }
            }
        }
        if (isset($this->info['is_data_collector']) && $this->info['is_data_collector']) {
            $update = [&$this->info['file_id']];
            $this->db->prepare_Stmt("UPDATE tbl_app_file_main_data SET status_id = 0 WHERE file_id = ? ", $update);
        }
        $arr = ['type' => 'inv', 'main_id' => $Invoice_ID, 'action' => 0, 'date_time' => $date_time,
            'user_id' => $this->info['created_logged_id']];
        CommonFunctions::add_user_log($arr);

        if(isset($this->info['maintenance_id'])){
            $maintenance_id = $this->info['maintenance_id'];
            $this->db->prepare_Stmt("update  tbl_maintenance set invoice_number = ?,maintenance_status_id=2 where maintenance_id = ?", [&$Invoice_ID , &$maintenance_id]);
        }


        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query("COMMIT");
            token_unique::remove_token();
            return [$Invoice_ID, ($invoice_prefix . $inv_num)];
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query("ROLLBACK");
            return array_unique($error);
        }
    }

    public function validateCustomerLimitBalance() {
        $currency = $this->db->query('select Currency_ID,Customer_Limit_Balance AS Limit_Balance from tbl_customers where Customer_ID = "' . $this->info['Customer_ID'] . '"');
        $currency_data = $this->db->assoc($currency);
        $currency_id = $currency_data['Currency_ID'];
        $q = $this->db->query('SELECT 
                                    Account_ID
                                FROM
                                    tbl_chart_of_accounts
                                WHERE   
                                    main_id = "' . $this->info['Customer_ID'] . '"
                                AND 
                                    main_type = "cust" and sub_type = "main"
                ');
        $row_c = $this->db->assoc($q);
        $code = $row_c['Account_ID'];
        $sum = 0.0;
        $debit = $this->db->query('SELECT 
                                        Transaction_Amount,
                                        Currency_ID,
                                        Transaction_Type
                                    FROM
                                        tbl_accounting_transactions
                                    WHERE
                                        Account_ID = "' . $code . '"
                                    and current_year_id = "' . $this->year_id . '"
                ');
        while ($row = $this->db->assoc($debit)) {
            $amount = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['Currency_ID'], $currency_id, $row['Transaction_Amount']);
            if ($row['Transaction_Type'] == 'Credit') {
                $sum -= $amount;
            } else {
                $sum += $amount;
            }
        }
        $balance_data = array(
            'Balance' => $sum,
            'Limit_Balance' => $currency_data['Limit_Balance'],
            'currency' => $currency_id
        );
        return $balance_data;
    }

    public function getMaxInvoice($prefix, $is_actual = 0) {
        $yearid = $is_actual ? $this->year_id_actual : $this->year_id;
        $query = $this->db->query('SELECT MAX(Invoice_ID) AS Entry_ID 
            FROM tbl_invoices where 1=1 AND current_year_id = "' . $yearid . '" '
                . 'and invoice_prefix = "' . $prefix . '" and is_actual = "' . $is_actual . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $Invoice = $row['Entry_ID'] + 1;
        else
            $Invoice = 1;
        return $Invoice;
    }

    public function getStatusName($code) {
        return StatusCodes::getStatus($code);
    }

    public function getInvoiceDeliveryNoteListDetails($ID) {
        $data = array();
        $query = $this->db->query('select * from invoice_delivery_note_list WHERE ID = "' . $ID . '"');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getInvoiceNumbers() {
        $data = array();
        $today = Date::getToday();
        $totalPrice = 0;
        $query1 = $this->db->query('SELECT
                                        COUNT(Invoice_ID) AS count
                                    FROM
                                        tbl_invoices
                                    WHERE
                                        Invoice_Date = "' . $today . '"
                                    ');
        $Inv = $this->db->assoc($query1);
        $InvNb = $Inv['count'];
        $Legal = $this->db->query('SELECT
                                        Invoice_ID,
                                        Invoice_Net_Total AS Total,
                                        Invoice_Currency
                                    FROM
                                        tbl_invoices
                                    WHERE
                                        Invoice_Date = "' . $today . '"
                                    ');
        while ($row = $this->db->assoc($Legal)) {
            $totalPrice += CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Invoice_Currency'], $row['Total']);
        }
        $data['count'] = $InvNb;
        $data['Total'] = $totalPrice;
        return $data;
    }

    public function getTotalInvoiceReturn() {
        $data = array();
        $today = Date::getToday();
        $totalPrice = 0;
        $query = $this->db->query('SELECT
                                        i.Invoice_Currency,
                                        r.Return_Invoice_Total AS Total
                                    FROM
                                        tbl_accounting_return_invoices r
                                    LEFT JOIN
                                        tbl_invoices i
                                    ON
                                        i.Invoice_ID = r.Invoice_Purchase_ID
                                    WHERE
                                        r.Return_Invoice_Date  = "' . $today . '"
                                    AND 
                                        r.Is_Customer_Invoice = 1
                                ');
        while ($row = $this->db->assoc($query)) {
            $totalPrice += CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Invoice_Currency'], $row['Total']);
        }
        $query1 = $this->db->query('SELECT  
                                        p.Currency_ID,
                                        p.Product_Price * (r.Return_Quantity + r.Damaged_Quantity) AS Total
                                    FROM
                                        tbl_garage_load_returns r
                                    LEFT JOIN
                                        tbl_stock_products p
                                    ON
                                        r.Product_ID = p.Product_ID
                                    LEFT JOIN
                                        tbl_garage_loading_order l
                                    ON
                                        l.Loading_Order_ID = r.Loading_Order_ID
                                    WHERE
                                        Loading_Order_Date = "' . $today . '"
                                    AND 
                                        p.Status_ID = 1
                                    ');
        while ($row1 = $this->db->assoc($query1)) {
            $totalPrice += CurrencyFactory::returnPriceInDefaultCurrencyValue($row1['Currency_ID'], $row1['Total']);
        }
        $data['total'] = round($totalPrice);
        return $data;
    }

    //    private function returnExactBalance($code, $currency_id, $from_date, $to_date, $opening_balance, $back_up = false) {
    //        $report = new Report();
    //        $cust_account_code = JV::getAccountCodeByID($code);
    //        $balance = $report->returnExactBalance($cust_account_code, $currency_id, $from_date, $to_date, $opening_balance, $back_up)['Balance'];
    //        if ($balance > 0)
    //            $balance = 0;
    //        else
    //            $balance = $balance * (-1);
    //        return $balance;
    //    }
    //    public function getSalesAccounts() {
    //        $data = array();
    //        $query = $this->db->query('SELECT 
    //                                        *
    //                                    FROM 
    //                                        tbl_chart_of_accounts
    //                                    WHERE 
    //                                        LEFT(Account_Code,2) = 70
    //                                    OR 
    //                                        LEFT(Account_Code,2) = 71
    //                ');
    //        while ($row = $this->db->assoc($query))
    //            $data[] = $row;
    //        return $data;
    //    }
    public function addServicesInvoice() {
//        $check = JV::checkCurrentYear($this->info['Invoice_Date'], $this->info['Invoice_Date'], $this->info['is_actual']);
//        if ($check !== '') {
//            $error = array();
//            $error[0] = $check;
//            return $error;
//        }
        $quer = $this->db->query('SELECT MAX(Invoice_ID) AS Max_Invoice FROM tbl_inventory_services_invoices WHERE current_year_id = "' . $this->year_id . '" and Is_Actual = "' . $this->info['is_actual'] . '"');
        $row = $this->db->fetch($quer);
        $Invoice_ID = $row['Max_Invoice'] + 1;
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $main_data = [&$Invoice_ID,
            &$this->info['Customer_ID'],
            &$this->info['Invoice_Date'],
            &$this->info['Currency_ID'],
            &$this->info['Invoice_Due_Date'],
            &$this->info['Invoice_Net_Total'],
            &$this->info[0],
            &$this->year_id,
            &$this->info['is_actual']];
        $this->db->prepare_Stmt('INSERT INTO tbl_inventory_services_invoices (
                                            Invoice_ID,
                                            Customer_ID, 
                                            Invoice_Date, 
                                            Currency_ID, 
                                            Invoice_Due_Date, 
                                            Invoice_Net_Total, 
                                            Logged_ID,
                                            current_year_id,
                                            Is_Actual
                                            ) 
                                        VALUES (?,?,?,?,?,?,?,?,?)', $main_data);
        $id = $this->db->id();
        $customer = $this->db->query("SELECT 
                                            Account_ID 
                                        FROM 
                                            tbl_chart_of_accounts
                                        WHERE 
                                            main_id = '" . $this->info['Customer_ID'] . "'
                                        AND 
                                            main_type = 'cust' and sub_type = 'main'");
        $customer_code = $this->db->assoc($customer)['Account_ID'];
        //        if ($this->info['is_actual'] == 1)
        $flag = $this->info['is_actual'];
        //        else
        //            $flag = null;
        foreach ($this->info['Services'] as $item) {
            $det_data = [&$id,
                &$item['Service_Description'],
                &$item['Account_Code'],
                &$item['Service_Amount']
            ];
            $this->db->prepare_Stmt('INSERT INTO tbl_inventory_servecies_invoice_details (
                                                        Invoice_ID,
                                                        Service_Description,
                                                        Account_ID,
                                                        Service_Amount
                                                        ) 
                                                VALUES (?,?,?,? )', $det_data);
            $id_det = $this->db->id();
            $jv = JV::returnJV($flag);
            $ref_num = 'SRV.' . $id_det;
            $dat_1 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $customer_code,
                "Transaction_Type" => "Debit",
                "Transaction_Amount" => $item['Service_Amount'],
                "Transaction_Date" => $this->info['Invoice_Date'],
                "Currency_ID" => $this->info['Currency_ID'],
                "Logged_ID" => $this->info[0],
                "Transaction_Description" => $item['Service_Description'],
                "Current_Ex_Rate" => "0",
                "main_id" => $id,
                "main_type" => "sin"
            ];
            JV::addTransaction($dat_1, $flag);
            $dat_2 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $item['Account_Code'],
                "Transaction_Type" => "Credit",
                "Transaction_Amount" => $item['Service_Amount'],
                "Transaction_Date" => $this->info['Invoice_Date'],
                "Currency_ID" => $this->info['Currency_ID'],
                "Logged_ID" => $this->info[0],
                "Transaction_Description" => $item['Service_Description'],
                "Current_Ex_Rate" => "0",
                "main_id" => $id,
                "main_type" => "sin"
            ];
            JV::addTransaction($dat_2, $flag);
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function viewServicesInvoices($from_date = null, $to_date = null) {
        $data = array();
        $condition = '';
        if (!is_null($from_date) and ! is_null($to_date))
            $condition .= ' WHERE Invoice_Date >= "' . $from_date . '" and Invoice_Date <= "' . $to_date . '"';
        $query = $this->db->query('SELECT 
                                        s.*,
                                        c.Customer_Name,
                                        cy.Currency_Symbol
                                    FROM 
                                        tbl_inventory_services_invoices s
                                    LEFT JOIN 
                                        tbl_customers c
                                    ON 
                                        s.Customer_ID = c.Customer_ID
                                    LEFT JOIN 
                                        tbl_common_currency cy
                                    ON 
                                        s.Currency_ID = cy.Currency_ID 
                ' . $condition);
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        return $data;
    }

    public function viewServicesDetails($invoice_id) {
        $data = array();
        $query = $this->db->query('SELECT 
                                        d.*,
                                        a.*,
                                        s.*,
                                        c.Customer_Name,
                                        cy.Currency_Symbol
                                    FROM 
                                        tbl_inventory_servecies_invoice_details d
                                    LEFT JOIN 
                                        tbl_inventory_services_invoices s
                                    ON 
                                        s.Invoice_ID_Auto = d.Invoice_ID
                                    LEFT JOIN 
                                        tbl_customers c
                                    ON 
                                        s.Customer_ID = c.Customer_ID
                                    LEFT JOIN 
                                        tbl_common_currency cy
                                    ON 
                                        s.Currency_ID = cy.Currency_ID
                                    LEFT JOIN 
                                        tbl_chart_of_accounts a
                                    ON 
                                        d.Account_ID = a.Account_ID
                                    WHERE 
                                        s.Invoice_ID_Auto = "' . $invoice_id . '"
                                            and s.current_year_id = "' . $this->year_id . '"
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        return $data;
    }

    public function getInvoiceByDueDate($week = null, $daily = null, $month = null, $year = null) {
        $data = array();
        $totalPrice = 0.0;
        $condition = '';
        $today = Date::getToday();
        $default_currency = CurrencyFactory::getDefaultCurrency();
        $Currency_Symbol = $this->db->query('SELECT Currency_Symbol FROM tbl_common_currency WHERE Currency_ID = "' . $default_currency . '"');
        $currency_row = $this->db->assoc($Currency_Symbol);
        $curr_symbol = $currency_row['Currency_Symbol'];
        if (!is_null($year)) {
            $condition .= 'AND YEAR(i.Invoice_Due_Date)  ="' . $year . '"';
        }
        if (!is_null($month)) {
            $condition .= 'AND MONTH(i.Invoice_Due_Date)  ="' . $month . '"';
        }
        if (!is_null($week)) {
            $condition .= ' AND WEEKOFYEAR(i.Invoice_Due_Date)= "' . $week . '"';
        }
        if (!is_null($daily)) {
            $condition .= ' AND i.Invoice_Due_Date = "' . $daily . '"';
        }
        $query = $this->db->query('SELECT 
										i.Invoice_ID,
										i.Invoice_Net_Total,
									    i.Invoice_Currency,
									    i.Invoice_Due_Date,
									    i.Invoice_Paid_Amount,
										c.Currency_Symbol,
										cu.Customer_ID,
										cu.Customer_Name,
										cu.Customer_Email,
										cu.Customer_Phone,
										cu.Customer_Company
									FROM	
										   tbl_invoices i
								    LEFT JOIN
											tbl_common_currency c
									ON
										  i.Invoice_Currency= c.Currency_ID
								    LEFT JOIN 
											tbl_customers cu
									ON 
											i.Customer_ID = cu.Customer_ID
								    WHERE
										i.Invoice_Net_Total > i.Invoice_Paid_Amount
									' . $condition);
        $count = 0;
        while ($row = $this->db->assoc($query)) {
            $count++;
            $totalPrice += CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Invoice_Currency'], $row['Invoice_Net_Total']);
            $data[] = $row;
        }
        $data['Total'] = $totalPrice;
        $data['Count'] = $count;
        $data['Currency_Symbol'] = $curr_symbol;
        return $data;
    }

    //    public function addSalesOrder() {
    //
    //        $is_invoice = 1;
    //        if (!$this->stop_transaction_start_end)
    //            $this->db->query('START TRANSACTION;');
    //        $order = [&$this->info['Vendor_ID'], &$this->info['Order_Date'], &$this->info[0]];
    //        $this->db->prepare_Stmt("INSERT INTO tbl_garage_sales_order (Customer_ID,Sales_Order_Date,Logged_ID) VALUES (?,?,?)", $order);
    //        $parent_id = $this->db->id();
    //
    //        if (is_array($this->info['Items'])) {
    //            foreach ($this->info['Items'] as $item) {
    //                $product_quantity = Product::getConvertedQuantity($item['UOM_ID'], $item['Quantity'], $item['Item_ID']);
    //                $details = [&$parent_id, &$item['Item_ID'], &$product_quantity, &$item['Quantity'], &$item['UOM_ID']];
    //                $this->db->prepare_Stmt("INSERT INTO tbl_garage_sales_order_details (Sales_Order_ID,Product_ID,Quantity,Item_Quantity_Current,UOM_ID) VALUES (?,?,?,?,?) ", $details);
    //            }
    //        }
    //        //        if (is_array($this->info['Terms'])) {
    //        //            foreach ($this->info['Terms'] as $item) {
    //        //                $details = [&$parent_id, &$item['term_input'], &$is_invoice];
    //        //                $this->db->prepare_Stmt("INSERT INTO tbl_purchase_order_terms (Order_ID,Term_Text,Is_Invoice) VALUES (?,?,?) ", $details);
    //        //            }
    //        //        }
    //        $error = $this->db->error();
    //        if (empty($error)) {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query("COMMIT");
    //        } else {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query("ROLLBACK");
    //        }
    //        return array_unique($error);
    //    }
    public function getSalesOrderDetails($ID) {
        $data = array();
        $query = $this->db->query('SELECT 
                                       *
                                   FROM 
                                        delivered_sales_order
                                    WHERE 
                                        Order_ID = "' . smc_escape($ID) . '"
				');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    //    public function archiveDeleteInvoice() {
    //        $invoices = implode(",", $this->info['IDs']);
    //        $references = implode(",", $this->info['Ref']);
    //        $ref_ret = implode(",", $this->info['Ret']);
    //        if (!$this->stop_transaction_start_end)
    //            $this->db->query('START TRANSACTION');
    //        if ($this->info['archive'] == 0) {
    //            $this->db->query("UPDATE tbl_invoices SET Archive_Status = 1 WHERE Invoice_ID_Auto IN ({$invoices})");
    //        } else {
    //
    //            $this->db->query("DELETE FROM tbl_invoices  WHERE Invoice_ID_Auto IN ({$invoices})");
    //            $this->db->query("DELETE FROM tbl_accounting_return_invoices  WHERE Invoice_Purchase_ID IN ({$invoices}) AND Is_Customer_Invoice = 1");
    //            $this->db->query("DELETE FROM tbl_accounting_transactions  WHERE Transaction_Reference IN ('" . $references . "') or Transaction_Reference IN ('" . $ref_ret . "')");
    //        }
    //        $error = $this->db->error();
    //        if (empty($error)) {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query('COMMIT');
    //        }
    //        else {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query('ROLLBACK');
    //        }
    //        return array_unique($error);
    //    }
    public function editInvoice($return_inv_num = false) {
        $is_actual = !empty($this->info['is_actual']) ? $this->info['is_actual'] : 0;
        $check = CommonFunctions::check_lock_data(['type' => 'invoice', 'start_date' => $this->info['Invoice_Date'], 'is_actual' => $is_actual]);

//        $check = JV::checkCurrentYear($this->info['Invoice_Date'], $this->info['Invoice_Date'], $is_actual);
        if ($check !== '') {
            $error = array();
            $error[0] = $check;
            return $error;
        }
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $mydate = date("Y-m-d H:i:s");
        $today = $this->info['Invoice_Date'];
        //        $ref_num = "Inv." . $this->info['Invoice_ID_Auto'];
        $this->info['Logged_ID'] = isset($this->info['Logged_ID']) ? $this->info['Logged_ID'] : Session::getUserID();
        $date_time = isset($this->info['date_time']) ? $this->info['date_time'] : $mydate;
        $invoice_user_reference = isset($this->info['invoice_user_reference']) ? $this->info['invoice_user_reference'] : NULL;
        $branch_id = CommonBusiness::getBranchByDepot($this->info['Depot_ID']);
        $jv_query = $this->db->query("SELECT DISTINCT JV_ID,Current_Ex_Rate,is_actual FROM tbl_accounting_transactions  WHERE main_id='" . $this->info['Invoice_ID_Auto'] . "' AND main_type= 'inv' ");
        $jv_assoc = $this->db->assoc($jv_query);
        if (!empty($jv_assoc) && $jv_assoc['is_actual'] == $is_actual)
            $jv = $jv_assoc['JV_ID'];
        else
            $jv = JV::returnJV($is_actual);
        //        $rate
        $this->db->prepare_Stmt("DELETE FROM tbl_accounting_transactions  WHERE main_id= ? AND main_type= 'inv' ", [&$this->info['Invoice_ID_Auto']]);
        $this->info['Cash_Amount'] = !empty($this->info['Cash_Amount']) ? $this->info['Cash_Amount'] : 0;
        $this->info['Check_Amount'] = !empty($this->info['Check_Amount']) ? $this->info['Check_Amount'] : 0;
        $this->info['Other_Amount'] = !empty($this->info['Other_Amount']) ? $this->info['Other_Amount'] : 0;
        $this->info['Other_Account'] = !empty($this->info['Other_Account']) ? $this->info['Other_Account'] : NULL;
        $paid = $this->info['Card_Amount'] + $this->info['Cash_Amount'] + $this->info['Check_Amount'] + $this->info['Other_Amount'];
        $payment_paid_amount = 0;
        $remaining = $this->info['Invoice_Net_Total'] + $this->info['shipping'] - $paid;
        if (smc_session()['default_setting']['generate_pay_rec_from_inv_pur'] == 1) {
            $paid = 0;
            $payment_paid_amount = $this->info['Card_Amount'] + $this->info['Cash_Amount'] + $this->info['Check_Amount'] + $this->info['Other_Amount'];
            $remaining = $this->info['Invoice_Net_Total'] + $this->info['shipping'];
        }
        $customerAccount = $this->info['Customer_Account'];
        $status = 0;
        if (isset($this->info['Invoice_Status'])) {
            $status = $this->info['Invoice_Status'];
        } else {
            if (isset($this->info['pending_status']) && $this->info['pending_status'] == 3) {
                $status = 3;
            } else {
                if ($remaining == 0) {
                    $status = 2;
                } elseif ($remaining < ($this->info['shipping'] + $this->info['Invoice_Net_Total'])) {
                    $status = 1;
                }
            }
        }
        $signature_image ='';
        if(isset($this->info['signature_image'])){
            $signature = $this->info['signature_image'];
            $signatureFileName = uniqid().'.png';
            $signature = str_replace('data:image/png;base64,', '', $signature);
            $signature = str_replace(' ', '+', $signature);
            $data = base64_decode($signature);
            $file = upload_path.'signatures/'.$signatureFileName;
            file_put_contents($file, $data);
            $signature_image = upload_url.'signatures/'.$signatureFileName;;

        }
        //        if ($remaining > 0) {
        //            $status = 1;
        //        } else {
        //            $status = 2;
        //        }
        $this->info['Account_Code'] = empty($this->info['Account_Code']) ? smc_session()['user_accounts']['sales_account_id'] : $this->info['Account_Code'];
        $job_trans_type = smc_session()['default_setting']['job_transaction_type'];
        $this->info['Invoice_Description'] = !empty($this->info['Invoice_Description']) ? $this->info['Invoice_Description'] : '';
        $this->info['is_invoice_total_on_shipping'] = empty($this->info['is_invoice_total_on_shipping']) ? 0 : 1;
        $this->info['trans_on_change_status'] = empty($this->info['trans_on_change_status']) ? 0 : 1;
        $sales_id = (smc_session()['default_setting']['sales_man_as_logged_user'] == 1 && empty($this->info['Sales_ID']) && !empty(smc_session()['user_details']['Employee_ID'])) ? smc_session()['user_details']['Employee_ID'] : (!empty($this->info['Sales_ID']) ? $this->info['Sales_ID'] : null);
        $rate = !empty($this->info['Invoice_Currency_Rate']) ? $this->info['Invoice_Currency_Rate'] : CurrencyFactory::getLastExRate($this->info['Invoice_Currency']);
        $second_rate = !empty($this->info['second_currency_rate']) ? $this->info['second_currency_rate'] : CurrencyFactory::getSecondCurrencyLastExRate($this->info['Invoice_Currency']);
        $this->info['currency_round'] = !empty($this->info['currency_round']) ? $this->info['currency_round'] : 0;
        $invoice_type = (isset($this->info['invoice_type']) ? $this->info['invoice_type'] : (isset($this->info['pending_status']) && $this->info['pending_status'] == 3 ? 3 : 1));
        $is_committed = (isset($this->info['is_committed']) ? $this->info['is_committed'] : (isset($this->info['pending_status']) && $this->info['pending_status'] == 3 ? 0 : 1));
        $is_postponed_change = 0;
        $old_date_time = $mydate;
        $old_created_logged_id = smc_session()['user_logged_id'];
        $old_date_created = $mydate;
        $update_stock = [&$this->info['Invoice_ID_Auto']];
        $invoice_num = '';
        $main_nb = '';
        $prefix = '';
        $invoice_app_id = empty($this->info['invoice_app_id']) ? 0 : $this->info['invoice_app_id'];
        $app_branch_id = empty($this->info['app_branch_id']) ? 0 : $this->info['app_branch_id'];
        $app_user_id = empty($this->info['app_user_id']) ? 0 : $this->info['app_user_id'];
        $option_arr = array();
        $query = $this->db->query('select p.invoice_detail_id,p.product_id,p.UOM_ID as uom_id,
            p.option_quantity as qty
            from tbl_invoice_product_options p
            join tbl_invoice_products_details d on d.Entery_ID = p.invoice_detail_id 
            where d.Invoice_ID_Auto = "' . $this->info['Invoice_ID_Auto'] . '"');
        while ($row = $this->db->assoc($query)) {
            $option_arr[$row['invoice_detail_id']][] = $row;
        }
//        echo"<pre>";
//                die(print_r($option_arr));

        $query = $this->db->query("SELECT 
                                        p.Product_ID,
                                        p.Item_Quantity_Current as Current_Quantity,
                                        p.Product_Quantity  as Quantity,
                                        p.UOM_ID,p.qty_link,
                                        p.unit_cost,p.Product_Net_Price,
                                        i.Invoice_Currency AS Currency_ID,
                                        p.depot_id as Depot_ID,
                                        i.current_rate,
                                        i.date_time,
                                        i.invoice_prefix, i.is_actual,
                                        i.Invoice_ID,i.created_logged_id,i.date_created,p.expiry_date,
                                        i.invoice_app_id,i.app_branch_id,i.app_user_id,p.lot_nb,p.serial_nb,pr.is_service,
                                        i.Customer_ID,p.Entery_ID
                                    FROM 
                                        tbl_invoice_products_details p
                                    join tbl_invoices i on i.Invoice_ID_Auto = p.Invoice_ID_Auto
                                    join tbl_stock_products pr on pr.Product_ID = p.Product_ID
                                    WHERE 
                                        p.Invoice_ID_Auto = '" . $this->info['Invoice_ID_Auto'] . "' 
                                            and (isnull(p.Delivery_Report_ID) or p.Delivery_Report_ID = 0)
                ");
        while ($row = $this->db->assoc($query)) {
            //if already filled keep it as it is, it may be filled from sync, app. ditribution,..
            $invoice_app_id = empty($row['invoice_app_id']) ? $invoice_app_id : $row['invoice_app_id'];
            $app_branch_id = empty($row['app_branch_id']) ? $app_branch_id : $row['app_branch_id'];
            $app_user_id = empty($row['app_user_id']) ? $app_user_id : $row['app_user_id'];
            $main_nb = $row['Invoice_ID'];
            $invoice_num = $row['invoice_prefix'] . $row['Invoice_ID'];
            $prefix = $row['invoice_prefix'];
            $old_created_logged_id = $row['created_logged_id'];
            $old_date_time = $row['date_time'];
            $old_date_created = $row['date_created'];
            $old_expiry_date = !empty($row['expiry_date']) ? $row['expiry_date'] : null;
            $old_lot_nb = !empty($row['lot_nb']) ? $row['lot_nb'] : '';
            $old_serial_nb = !empty($row['serial_nb']) ? $row['serial_nb'] : '';
            $ProductQuantityRate = $row['Quantity'] / $row['Current_Quantity'];
            $costdata = [
                "Product_ID" => '', //$row['Product_ID'],
                "Quantity" => '', //$row['Quantity'],
                "Unit_Cost" => '',
                "unit_price" => $row['Product_Net_Price'],
                "Currency_ID" => $row['Currency_ID'],
                "date_time" => $row['date_time'],
                "date_time_now" => $date_time,
                "current_rate" => $row['current_rate'],
                "depot_id" => $row['Depot_ID'],
                "trans_date" => $this->info['Invoice_Date'],
                "current_quantity" => '', //$row['Current_Quantity'],
                "uom_id" => '', //$row['UOM_ID'],
                "is_actual" => $row['is_actual'],
                "expiry_date" => $old_expiry_date,
                "lot_nb" => $old_lot_nb,
                "serial_nb" => $old_serial_nb,
                "main_id" => $this->info['Invoice_ID_Auto'],
                "is_service" => $row['is_service'],
                "main_nb" => $invoice_num,
                "customer_id" => $row['Customer_ID']
            ];
            $option_arr_temp = !empty($option_arr[$row['Entery_ID']]) ? $option_arr[$row['Entery_ID']] : array();

            $product_links = CommonBusiness::get_product_links($row['Product_ID'], $row['UOM_ID'], $row['Quantity'], $row['Current_Quantity'], '-', 0, $option_arr_temp);
 
            $is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $row['Product_ID'] . '" ');
            $is_rate_row = $this->db->assoc($is_rate_query); 
            $is_rate_type_one = $is_rate_row['is_rate_type_one'];
            $is_rate_type_two = $is_rate_row['is_rate_type_two'];
            $rate_type_one = smc_session()['default_setting']['rate_type_one'];
            $rate_type_two = smc_session()['default_setting']['rate_type_two'];

            $effect_qty_link_product  = $is_rate_row['effect_qty_link_product'];

            
            foreach ($product_links as $link) {
                $link_is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $link['Product_ID'] . '" ');
                $link_is_rate_row = $this->db->assoc($link_is_rate_query); 
                $link_is_rate_type_one = $link_is_rate_row['is_rate_type_one'];
                $link_is_rate_type_two = $link_is_rate_row['is_rate_type_two'];

                $costdata["Quantity"] = $link['Quantity'];
                $costdata["current_quantity"] = $link['current_quantity'];

                if($is_rate_type_one == 1 && $link_is_rate_type_one == 1 && $rate_type_one > 0 && $link['operation'] == '-'){
                    $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_one)/100));
                    $costdata["current_quantity"] = $costdata['Quantity'];

                }
                if($is_rate_type_two == 1 && $link_is_rate_type_two == 1  && $rate_type_two > 0 && $link['operation'] == '-'){
                    $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_two)/100));
                    $costdata["current_quantity"] = $costdata['Quantity'];

                }

                if($effect_qty_link_product == 1){
                    $costdata["Quantity"] = $row['qty_link'];
                    $costdata["current_quantity"] = $row['qty_link'];
                }


                $costdata["Product_ID"] = $link['Product_ID'];
                $costdata["uom_id"] = $link['uom_id'];
                $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                if (!empty($link['is_main_prdct']))
                    $costdata['Unit_Cost'] = $row['unit_cost'];
                else {
                    $cost = CommonBusiness::viewCurrentProductCost($link['Product_ID']);
                    $costdata['Unit_Cost'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                }
                 // echo $costdata['Unit_Cost'].='==';
                self::updateLinkQuantities($costdata, "edit_invoice_old", ($link['operation'] == '+' ? '-' : '+'));
                //                    echo $cost.='==';
                //                $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
            }
            //die();
            //            self::updateLinkQuantities($costdata, "edit_invoice_old", ($row['operation'] == '+' ? '-' : '+'));
        }
        $Bon_Number = isset($this->info['Bon_Number']) ? $this->info['Bon_Number'] : 0;
        $Inv_Type = isset($this->info['Inv_Type']) ? $this->info['Inv_Type'] : 2;
        $Delivery_Time = isset($this->info['Delivery_Time']) ? $this->info['Delivery_Time'] : '';
        $Is_Delivery = isset($this->info['Is_Delivery']) ? $this->info['Is_Delivery'] : 0;
        $Close_ID = isset($this->info['Close_ID']) ? $this->info['Close_ID'] : 0;
        $table_id = isset($this->info['table_id']) ? $this->info['table_id'] : 0;
        $Persons_Count = isset($this->info['Persons_Count']) ? $this->info['Persons_Count'] : 0;
        $pos_customer_id = isset($this->info['pos_customer_id']) ? $this->info['pos_customer_id'] : 0;
        $service_percant = isset($this->info['service_percant']) ? $this->info['service_percant'] : 0;
        $service_value = isset($this->info['service_value']) ? $this->info['service_value'] : 0;
        $is_app = isset($this->info['is_app']) ? $this->info['is_app'] : 0;
        $order_id_online = isset($this->info['order_id_online']) ? $this->info['order_id_online'] : 0;
        $address_id = isset($this->info['address_id']) ? $this->info['address_id'] : 0;
        $driver_id = isset($this->info['driver_id']) ? $this->info['driver_id'] : 0;
        $cash_amount = isset($this->info['cash_amount']) ? $this->info['cash_amount'] : 0;
        $posponted_type = !empty($this->info['posponted_type']) ? $this->info['posponted_type'] : 0;
        $postponed_note = !empty($this->info['postponed_note']) ? $this->info['postponed_note'] : '';
        $postponed_date_time = !empty($this->info['postponed_date_time']) ? $this->info['postponed_date_time'] : NULL;
        $main_nb = !empty($this->info['Invoice_ID']) ? $this->info['Invoice_ID'] : $main_nb;
        $prefix = !empty($this->info['invoice_prefix']) ? $this->info['invoice_prefix'] : $prefix;
        $this->info['shipping_company_id'] = !empty($this->info['shipping_company_id']) ? $this->info['shipping_company_id'] : NULL;
        $this->info['shipping_note'] = !empty($this->info['shipping_note']) ? $this->info['shipping_note'] : NULL;
        $ship_comp_acc_id = !empty($this->info['shipp_comp_acc_id']) ? $this->info['shipp_comp_acc_id'] : null;
        $contra_id = !empty($this->info['contra_id']) ? $this->info['contra_id'] : null;
        $customer_branch_id = !empty($this->info['customer_branch_id']) ? $this->info['customer_branch_id'] : null;
        $this->info['vat1_total'] = !empty($this->info['vat1_total']) ? $this->info['vat1_total'] : $this->info['Invoice_VAT'];
        $this->info['vat2_total'] = !empty($this->info['vat2_total']) ? $this->info['vat2_total'] : 0;
        $customer_name_alias = isset($this->info['customer_name_alias']) ? $this->info['customer_name_alias'] : '';
        $customer_address_alias = isset($this->info['customer_address_alias']) ? $this->info['customer_address_alias'] : '';
        
        
        $up_main = [
            &$main_nb, &$prefix,
            &$this->info['Customer_ID'],
            &$this->info['Invoice_Date'],
            &$this->info['Invoice_Currency'],
            &$this->info['Invoice_VAT'],
            &$this->info['vat1_total'],
            &$this->info['vat2_total'],
            &$this->info['Invoice_Sub_Total'],
            &$this->info['Invoice_Discount'],
            &$this->info['discount_amount'],
            &$this->info['Invoice_Net_Total'],
            &$this->info['tax_amount'],
            &$this->info['Invoice_Due_Date'],
            &$this->info['Invoice_Description'],
            &$paid,
            &$status,
            &$this->info['Logged_ID'],
            &$this->info['Depot_ID'],
            &$this->info['shipping'],
            &$this->info['truck'],
            &$rate,
            &$second_rate,
            &$branch_id,
            &$this->info['Class_ID'],
            &$sales_id,
            &$this->info['Account_Code'],
            &$this->info['job_id'],
            &$date_time,
            &$Bon_Number, &$Inv_Type, &$Delivery_Time, &$Is_Delivery, &$Close_ID, &$table_id,
            &$Persons_Count, &$pos_customer_id, &$service_percant,
            &$service_value, &$is_app, &$order_id_online, &$address_id, &$cash_amount,
            &$posponted_type, &$postponed_date_time, &$invoice_type, &$is_committed, &$is_postponed_change, &$postponed_note,
            &$invoice_app_id, &$app_branch_id, &$app_user_id,
            &$this->info['project_id'], &$this->info['shipping_company_id'],
            &$this->info['shipping_note'],
            &$is_actual, &$invoice_user_reference, &$ship_comp_acc_id,
            &$this->info['is_invoice_total_on_shipping'], $this->info['trans_on_change_status'], &$contra_id, &$this->info['currency_round'],
            &$customer_branch_id, $customer_name_alias, $customer_address_alias,&$this->info['po'],&$this->info['project_name_inv'],&$this->info['project_code'],&$this->info['job_inv'],&$this->info['our_ref'],&$this->info['supply_date'],
            &$this->info['r_d_sph']
            , &$this->info['c_d_cyl']
            , &$this->info['c_d_ax']

            , &$this->info['c_d_sph']
            , &$this->info['l_d_cyl']
            , &$this->info['l_d_ax']

            , &$this->info['r_r_sph']
            , &$this->info['c_r_cyl']
            , &$this->info['c_r_ax']

            , &$this->info['c_r_sph']
            , &$this->info['l_r_cyl']
            , &$this->info['l_r_ax']
            ,  $signature_image
            , &$this->info['cl_r_sph']
            , &$this->info['cl_r_cyl']
            , &$this->info['cl_r_axis']
            , &$this->info['cl_r_ipd']
            , &$this->info['cl_l_sph']
            , &$this->info['cl_l_cyl']
            , &$this->info['cl_l_axis']
            , &$this->info['cl_l_ipd']
            , &$driver_id
            , &$this->info['from_place']
            , &$this->info['to_place']

            , &$this->info['Invoice_ID_Auto']
        ];
        $this->db->prepare_Stmt("UPDATE 
                                    tbl_invoices 
                                SET
                                Invoice_ID = ?,invoice_prefix=?,
                                    Customer_ID = ?,
                                    Invoice_Date = ?,
                                    Invoice_Currency = ?,
                                    Invoice_VAT = ?,
                                    vat1_total = ?,
                                    vat2_total = ?,
                                    Invoice_Sub_Total = ?,
                                    Invoice_Discount = ?,
                                    discount_amount = ?,
                                    Invoice_Net_Total = ?,
                                    tax_amount=?,
                                    Invoice_Due_Date = ?,
                                    Invoice_Description=?,
                                    Invoice_Paid_Amount = ?,
                                    Invoice_Status = ?,
                                    Logged_ID = ?,
                                    Depot_ID = ?,
                                    Invoice_Shipping = ?,
                                    truck = ?,
                                    current_rate = ?,second_currency_rate=?,
                                    branch_id = ?,
                                    Class_ID = ?,
                                    Sales_ID = ?,
                                    Account_ID = ?,job_id=?,date_time=?,
                                    Bon_Number=?,Inv_Type=?,Delivery_Time=?,Is_Delivery=?,Close_ID=?,
                                    table_id=?,Persons_Count=?,pos_customer_id=?,service_percant=?,
                                    service_value=?,is_app=?,order_id_online=?,address_id=?,cash_amount=?
                                    ,is_main_transfer = 0,posponted_type=?,postponed_date_time=?,invoice_type=?,is_committed=?,
                                        is_postponed_change=?,postponed_note=?,invoice_app_id=?,app_branch_id=?,app_user_id=?,project_id=?,shipping_company_id = ?,shipping_note = ?,is_actual=?,invoice_user_reference = ?,
                                        ship_comp_acc_id=?,is_invoice_total_on_shipping=?,trans_on_change_status=?,contra_id=?,currency_round = ?,
                                        customer_branch_id = ?,customer_name_alias=?,customer_address_alias=?,po=?,project_name_inv=?,project_code=?,job_inv=?,our_ref=?,supply_date=?,r_d_sph=?,c_d_cyl=?,c_d_ax=?,c_d_sph=?,l_d_cyl=?,l_d_ax=?,r_r_sph=?,c_r_cyl=?,c_r_ax=?,c_r_sph=?,l_r_cyl=?,l_r_ax=?,signature_image=?,cl_r_sph=?,cl_r_cyl=?,cl_r_axis=?,cl_r_ipd=?,cl_l_sph=?,cl_l_cyl=?,cl_l_axis=?
                                        ,cl_l_ipd=?
                                        ,driver_id = ?
                                        ,from_place  = ?
                                        ,to_place = ?
                                WHERE 
                                    Invoice_ID_Auto = ?
                 ", $up_main);
        $ref_num = 'Inv.' . $invoice_num;
        $this->db->prepare_Stmt("DELETE criteria FROM  tbl_invoice_product_criteria criteria
                                inner join tbl_invoice_products_details details on details.Entery_ID = criteria.Entery_ID
                                inner join tbl_invoices invoices on invoices.Invoice_ID_Auto = details.Invoice_ID_Auto 
                                where invoices.Invoice_ID_Auto = ?", $update_stock);
        $this->db->prepare_Stmt("DELETE FROM tbl_invoice_products_details  WHERE Invoice_ID_Auto = ?", $update_stock);
        $prod_arr = array();
        $prod_ids_arr = array();
        $customerName = $this->info['Customer_Name'];
        $curr_symbol = $this->info['CurrencySymbole'];
        $desc = !empty($this->info['Invoice_Description']) ? $this->info['Invoice_Description'] : ($customerName . ' bought products with ' . round(($this->info['Invoice_Net_Total'] + $this->info['shipping']), 2) . ' ' . $curr_symbol);
        $is_transaction_jv = ($Inv_Type == 2 && $status != 3);
        CommonBusiness::update_trans_record_current('inv', $this->info['Invoice_ID_Auto']);
        $expiry_valid_arr = array();
        $serial_valid_arr = array();
        $lot_valid_arr = array();
        $qty_valid_arr = array();
        $depot_arr = array();
        foreach ($this->info['Products'] as $item) {
            $item["vat2_percent"] = !empty($item["vat2_percent"]) ? $item["vat2_percent"] : 0;
            $item["vat2_amount"] = !empty($item["vat2_amount"]) ? $item["vat2_amount"] : 0;
            $prod_ids_arr[] = $item['Product_ID'];
            $ProductID = $item['Product_ID'];
            //            $ProductQuantity = Product::getConvertedQuantity($item['UOM_ID'], $item['Item_Quantity'], $item['Product_ID']);
            $ProductQuantityRate = Product::getConvertedQuantity($item['UOM_ID'], 1, $item['Product_ID']);
            $ProductQuantity = $ProductQuantityRate * $item['Item_Quantity'];
            $ProductDiscount = $item['Item_Discount'];
            $ProductNetPrice = $item['Item_Price'];
            $Product_Total_Price = $item['Product_Total_Price'];
            $Product_Description = !empty($item['product_description']) ? $item['product_description'] : '';
            $purchase_detail_id = !empty($item['purchase_detail_id']) ? $item['purchase_detail_id'] : null;
            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => ($Product_Total_Price),
                "description" => $Product_Description, "vat_amount" => ($item['vat_val'] + $item['vat2_amount']));
            $expiry_date = !empty($item['expiry_date']) ? $item['expiry_date'] : null;
            $depot_detail_id = !empty($item['depot_id']) ? $item['depot_id'] : $this->info['Depot_ID'];
            $vehicle_id = !empty($item['vehicle_id']) ? $item['vehicle_id'] : null;
            $employee_id = !empty($item['employee_id']) ? $item['employee_id'] : null;
            $commission = !empty($item['commission']) ? $item['commission'] : 0;
            $lot_nb = !empty($item['lot_nb']) ? $item['lot_nb'] : '';
            $serial_nb = !empty($item['serial_nb']) ? $item['serial_nb'] : '';
            $item['delivery_id'] = !empty($item['delivery_id']) ? $item['delivery_id'] : null;
            $unit_cost = !empty($item['delivery_cost']) ? $item['delivery_cost'] : 0;
            $item['is_service'] = !empty($item['is_service']) ? $item['is_service'] : 0;
            $item['subscription_fees_detail_id'] = empty($item['subscription_fees_detail_id']) ? NULL : $item['subscription_fees_detail_id'];
            if (empty($depot_arr[$depot_detail_id]))
                $depot_arr[$depot_detail_id] = $depot_detail_id;
            if (empty($item['delivery_id'])) {
                $costdata = [
                    "Product_ID" => $ProductID,
                    "Quantity" => $ProductQuantity,
                    "Unit_Cost" => "",
                    "unit_price" => $ProductNetPrice,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "date_time" => $old_date_time,
                    "date_time_now" => $date_time,
                    "current_rate" => $rate,
                    "depot_id" => $depot_detail_id,
                    "trans_date" => $this->info['Invoice_Date'],
                    "current_quantity" => $item['Item_Quantity'],
                    "uom_id" => $item['UOM_ID'],
                    "is_actual" => $is_actual,
                    "expiry_date" => $expiry_date,
                    "lot_nb" => $lot_nb,
                    "serial_nb" => $serial_nb,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "is_service" => $item['is_service'],
                    "main_nb" => $invoice_num,
                    "customer_id" => $this->info['Customer_ID']
                ];
                //                $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $ProductID . '"');
                //
                //                $count_row = $this->db->rowsno($link_query);
                //                if ($count_row == 0) {
                //                    $cost = self::updateLinkQuantities($costdata, "edit_invoice_new", '-');
                //                    $unit_cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                //                } else {
                //                    while ($link = $this->db->assoc($link_query)) {
                //                        $link_qty = $link['quantity'] * $ProductQuantity;
                //                        $costdata["Quantity"] = $link_qty;
                //                        $costdata["current_quantity"] = $link['current_quantity'] * $ProductQuantity;
                //                        $costdata["Product_ID"] = $link['sub_product_id'];
                //                        $costdata["uom_id"] = $link['UOM_ID'];
                //                        $cost = self::updateLinkQuantities($costdata, "edit_invoice_new", $link['operation']);
                //                        $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                //                    }
                //                }
                $option_arr = !empty($item['options_arr']) ? json_decode($item['options_arr'], true) : array();

                $product_links = CommonBusiness::get_product_links($ProductID, $item['UOM_ID'], $ProductQuantity, $item['Item_Quantity'], '-', 0, $option_arr);
                //               echo"<pre>";die(print_r($product_links));
                
                $is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $item['Product_ID'] . '" ');
                $is_rate_row = $this->db->assoc($is_rate_query); 
                $is_rate_type_one = $is_rate_row['is_rate_type_one'];
                $is_rate_type_two = $is_rate_row['is_rate_type_two'];
                $rate_type_one = smc_session()['default_setting']['rate_type_one'];
                $rate_type_two = smc_session()['default_setting']['rate_type_two'];

                $effect_qty_link_product  = $is_rate_row['effect_qty_link_product'];

                
                
                foreach ($product_links as $link) {
                    $costdata["Quantity"] = $link['Quantity'];
                    $costdata["current_quantity"] = $link['current_quantity'];

                    if($is_rate_type_one == 1 && $link_is_rate_type_one == 1 && $rate_type_one > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_one)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"];

                    }
                    if($is_rate_type_two == 1 && $link_is_rate_type_two == 1  && $rate_type_two > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_two)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"];

                    }

                    if($effect_qty_link_product == 1){
                        $costdata["Quantity"] = $item['qty_link'];
                        $costdata["current_quantity"] = $item['qty_link'];
                    }

                     $costdata["Product_ID"] = $link['Product_ID'];
                    $costdata["uom_id"] = $link['uom_id'];
                    $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                    $cost = self::updateLinkQuantities($costdata, "edit_invoice_new", $link['operation']) * ($link['Quantity'] / ($ProductQuantityRate * $item['Item_Quantity']));
                    //                    echo $cost.='==';
                    $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                    if (!empty($expiry_date) && !empty(smc_session()['default_setting']['activate_expiry_qty_exist']) && empty($invoice_app_id)) {
                        $expiry_valid_arr['expiry'][] = $expiry_date;
                        if (!isset($expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date]))
                            $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] = 0;
                        $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] += $link['Quantity'];
                    }
                    if (!empty($serial_nb) && !empty(smc_session()['default_setting']['activate_serial_qty_exist']) && empty($invoice_app_id)) {
                        $serial_valid_arr['serial'][] = $serial_nb;
                        if (!isset($serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb]))
                            $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] = 0;
                        $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] += $link['Quantity'];
                    }
                    if (!empty($lot_nb) && !empty(smc_session()['default_setting']['activate_lot_qty_exist']) && empty($invoice_app_id)) {
                        $lot_valid_arr['lot'][] = $lot_nb;
                        if (!isset($lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb]))
                            $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] = 0;
                        $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] += $link['Quantity'];
                    }
                    if (!empty($link['Quantity']) && empty(smc_session()['default_setting']['negative_sales']) && empty($invoice_app_id)) {
                        if (!isset($qty_valid_arr[$link['Product_ID']][$depot_detail_id]))
                            $qty_valid_arr[$link['Product_ID']][$depot_detail_id] = 0;
                        $qty_valid_arr[$link['Product_ID']][$depot_detail_id] += $link['Quantity'];
                    }
                }
            }

            $Added_Amount = isset($item['Added_Amount']) ? $item['Added_Amount'] : 0;
            $prod_disc_amt = !isset($item['Discount_Amount']) ? ($item['Item_Quantity'] * $item['Item_Price'] * $item['Item_Discount'] / 100) : $item['Discount_Amount'];
            $total_tax = empty($item['total_tax']) ? 0 : $item['total_tax'];
            //            echo $unit_cost . '=====';
            $prod = [
                &$this->info['Invoice_ID_Auto'],
                &$ProductID,
                &$ProductDiscount,
                &$prod_disc_amt,
                &$item['vat_percent'],
                &$item['vat_val'],
                &$item['vat2_percent'],
                &$item['vat2_amount'],
                &$ProductNetPrice,
                &$ProductQuantity,
                &$Product_Total_Price,
                &$unit_cost,
                &$item['Item_Quantity'],
                &$item['UOM_ID'],
                &$Product_Description,
                &$purchase_detail_id,
                &$expiry_date,
                &$Added_Amount, &$depot_detail_id, &$vehicle_id, &$employee_id, &$commission, &$total_tax,
                &$lot_nb, &$serial_nb, &$item['delivery_id'], &$mydate, &$item['subscription_fees_detail_id'], &$item['from_time'], &$item['to_time'], &$item['modify_date']
                , &$item['item_driver_id']
                , &$item['n_width']
                , &$item['n_height']
                , &$item['n_total']
                , &$item['qty_link']
                , &$item['is_collected_points']
            ];
            $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (" . (!empty($item['entry_id']) ? 'Entery_ID,' : '') . "
                                                                        Invoice_ID_Auto,
                                                                        Product_ID,
                                                                        Product_Discount,
                                                                        Discount_Amount,
                                                                        vat_percent,
                                                                        vat_amount,
                                                                        vat2_percent,
                                                                        vat2_amount,
                                                                        Product_Net_Price,
                                                                        Product_Quantity,
                                                                        Product_Total_Price,
                                                                        unit_cost,
                                                                        Item_Quantity_Current,
                                                                        UOM_ID,
                                                                        product_description,
                                                                        purchase_detail_id,
                                                                        expiry_date,
                                                                        Added_Amount,depot_id,vehicle_id,employee_id,
                                                                        commission,total_tax,lot_nb,serial_nb,Delivery_Report_ID,
                                                                        date_created,subscription_fees_detail_id,from_time,to_time,modify_date
                                                                        ,driver_id
                                                                        ,n_width
                                                                        ,n_height
                                                                        ,n_total
                                                                        ,qty_link
                                                                        ,is_collected_points
                                                                        ) 
                                                                    VALUES (
                                                                        " . (!empty($item['entry_id']) ? '"' . $item['entry_id'] . '",' : '') . "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
                                                                        )"
                    , $prod);
            $entry_id = $this->db->id();
            $this->db->prepare_Stmt('delete from tbl_invoice_product_add_ons where Entery_ID = ?', [&$entry_id]);
            if (!empty($item['add_ons'])) {
                $add_on_data = array('id' => $entry_id, 'add_ons' => $item['add_ons']);
                Invoicepos::addInvDetailAddOns($add_on_data);
            }

            $this->db->prepare_Stmt("DELETE FROM tbl_invoice_product_options where invoice_detail_id =?", [&$entry_id]);
            if (array_key_exists('options_arr', $item)) {
                $arr = array();
                $arr['options_arr'] = $item['options_arr'];
                $arr['id'] = $entry_id;
                Invoicepos::add_invoice_detail_options($arr);
            }
            if (!empty($item['criteria_details'])) {
                $criteria_details = $item['criteria_details'];
                foreach ($criteria_details as $details) {
                    $this->db->prepare_Stmt("INSERT INTO
                                        tbl_invoice_product_criteria 
                                        (Entery_ID,Quantity,criteria_detail_id,criteria_price,criteria_note)
                                        VALUES
                                        (?,?,?,?,?)
                    ", [&$entry_id, &$details['Quantity'], &$details['criteria_detail_id'],
                        &$details['criteria_price'], &$details['criteria_note']]);
                }
            }
            if ($is_transaction_jv && !empty($item['employee_id']) && !empty($item['commission'])) {
                $employee_acc_arr = Employee::viewEmployeeAccount($item['employee_id']);
                $dat_31 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $employee_acc_arr['exp'],
                    "Transaction_Type" => 'Debit',
                    "Transaction_Amount" => abs($this->info['currency_round']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_31, $is_actual);
                $dat_32 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $employee_acc_arr['inc'],
                    "Transaction_Type" => 'Credit',
                    "Transaction_Amount" => abs($this->info['currency_round']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_32, $is_actual);
            }
            //                        echo"<pre>";
            //                         $error = $this->db->error();
            //                    die(print_r($prod));
        }

        if (!empty($expiry_valid_arr)) {
            $expiry_valid = CommonBusiness::validate_expiry_qty_exist($expiry_valid_arr, $depot_arr);
            if (!empty($expiry_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['expiry_error', $expiry_valid];
            }
        }

        if (!empty($lot_valid_arr)) {
            $lot_valid = CommonBusiness::validate_lot_qty_exist($lot_valid_arr, $depot_arr);
            if (!empty($lot_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['lot_error', $lot_valid];
            }
        }
        if (!empty($serial_valid_arr)) {
            $serial_valid = CommonBusiness::validate_serial_qty_exist($serial_valid_arr, $depot_arr);
            if (!empty($serial_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['serial_error', $serial_valid];
            }
        }
        if (!empty($qty_valid_arr)) {
            $qty_valid = CommonBusiness::validate_product_qty_exist($qty_valid_arr, $depot_arr);
            if (!empty($qty_valid)) {
                if (!$this->stop_transaction_start_end)
                    $this->db->query('ROLLBACK');
                return ['qty_error', $qty_valid];
            }
        }


        //        echo $Inv_Type.'=='.$status;
        if ($is_transaction_jv) {
            //            echo'heree';
            $prod_str =implode( ',',$prod_ids_arr);
            $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $this->info['Account_Code'], $this->info['Invoice_Discount'], $this->info['shipping_account'], $this->info['shipping'], $this->info['tax_amount']);
            //            echo"<pre>";
            //        die(print_r($prod_arr));
            //            echo"<pre>";
            //        die(print_r($prod_trans_arr));
            //        $c_account = JV::getAccountCodeByID($customerAccount);
            $vat_account = Customer::returnCustomerVATAccount($this->info['Customer_ID'])['Account_ID'];
            $amount_novat = $this->info['Invoice_Net_Total'] - $this->info['Invoice_VAT'];

            foreach ($prod_trans_arr as $trans) {
                //            $trans_desc = $trans[]
                if (isset($trans['main'])) {
                    $trans_main = $trans['main'];
                    $data_trans = ["JV_ID" => $jv,
                        "Transaction_Reference" => (empty($trans_main['ref']) ? 'inv' : $trans_main['ref']),
                        "Transaction_Account" => $trans_main['trans_account'],
                        "Transaction_Type" => "Credit",
                        "Transaction_Amount" => $trans_main['trans_amount'],
                        "Transaction_Date" => $today,
                        "Currency_ID" => $this->info['Invoice_Currency'],
                        "Logged_ID" => $this->info['Logged_ID'],
                        "date_time" => $date_time,
                        "date_created" => $old_date_created,
                        "created_logged_id" => $old_created_logged_id,
                        "Transaction_Description" => (empty($trans_main['trans_desc']) ? $desc : $trans_main['trans_desc']),
                        "Current_Ex_Rate" => $rate,
                        "second_currency_rate" => $second_rate,
                        "main_id" => $this->info['Invoice_ID_Auto'],
                        "main_type" => "inv",
                        "branch_id" => $branch_id,
                        "due_date" => $this->info['Invoice_Due_Date'],
                        "subtype" => "inv",
                        "main_nb" => $main_nb,
                        "prefix" => $prefix,
                        "user_ref" => $invoice_user_reference,
                        "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                        "project_id" => $this->info['project_id'],
                        "salesman_id" => $sales_id
                    ];
                    JV::addTransaction($data_trans, $is_actual);
//                     $error = $this->db->error();
//            echo '<pre>';
//            print_r($error);
//            die('ok');
                }

                if (isset($trans['person'])) {
                    $trans_person = $trans['person'];
                    $cust_amount = smc_session()['default_setting']['merge_cust_supp_accounts'] == 1 ? ($trans_person['trans_amount'] + $this->info['currency_round'] ) : $trans_person['trans_amount'];
                    $data_trans = ["JV_ID" => $jv,
                        "Transaction_Reference" => $ref_num,
                        "Transaction_Account" => $customerAccount,
                        "Transaction_Type" => "Debit",
                        "Transaction_Amount" => $cust_amount,
                        "Transaction_Date" => $today,
                        "Currency_ID" => $this->info['Invoice_Currency'],
                        "Logged_ID" => $this->info['Logged_ID'],
                        "date_time" => $date_time,
                        "date_created" => $old_date_created,
                        "created_logged_id" => $old_created_logged_id,
                        "Transaction_Description" => (empty($trans_person['trans_desc']) ? $desc : $trans_person['trans_desc']) . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                        "Current_Ex_Rate" => $rate,
                        "second_currency_rate" => $second_rate,
                        "main_id" => $this->info['Invoice_ID_Auto'],
                        "main_type" => "inv",
                        "branch_id" => $branch_id,
                        "due_date" => $this->info['Invoice_Due_Date'],
                        "main_nb" => $main_nb,
                        "prefix" => $prefix,
                        "user_ref" => $invoice_user_reference,
                        "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                        "project_id" => $this->info['project_id'],
                        "salesman_id" => $sales_id,
                        "pos_customer_id" => $pos_customer_id
                    ];
                    JV::addTransaction($data_trans, $is_actual);
                }
            }

            if (smc_session()['default_setting']['merge_cust_supp_accounts'] == 0) {
                $trans_type = $this->info['currency_round'] < 0 ? 'Credit' : 'Debit';
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customerAccount,
                    "Transaction_Type" => $trans_type,
                    "Transaction_Amount" => abs($this->info['currency_round']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => $pos_customer_id
                ];
                JV::addTransaction($data_trans, $is_actual);
            }

            $discount_account = !empty(smc_session()['user_accounts']['discount_account']) ? smc_session()['user_accounts']['discount_account'] : $this->info['Account_Code'];
            $trans_disc_type = $this->info['currency_round'] > 0 ? 'Credit' : 'Debit';
            $data_disc = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $discount_account,
                "Transaction_Type" => $trans_disc_type,
                "Transaction_Amount" => abs($this->info['currency_round']),
                "Transaction_Date" => $today,
                "Currency_ID" => $this->info['Invoice_Currency'],
                "Logged_ID" => $this->info['Logged_ID'],
                "created_logged_id" => $old_created_logged_id,
                "Transaction_Description" => $desc,
                "date_created" => $old_date_created,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate,
                "main_id" => $this->info['Invoice_ID_Auto'],
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $this->info['Invoice_Due_Date'],
                "main_nb" => $main_nb,
                "prefix" => $prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id
            ];
            JV::addTransaction($data_disc, $is_actual);

            //        $dat_22 = array(
            //            "JV_ID" => $jv,
            //            "Transaction_Reference" => 'ship',
            //            "Transaction_Account" => $this->info['shipping_account'],
            //            "Transaction_Type" => "Debit",
            //            "Transaction_Amount" => $this->info['shipping'],
            //            "Transaction_Date" => $today,
            //            "Currency_ID" => $this->info['Invoice_Currency'],
            //            "Logged_ID" => $this->info['Logged_ID'],
            //            "Transaction_Description" => $desc,
            //            "Current_Ex_Rate" => $rate,
            //            "main_id" => $this->info['Invoice_ID_Auto'],
            //            "main_id" => $this->info['Invoice_ID_Auto'],
            //            "main_type" => "inv",
            //            "branch_id" => $branch_id,
            //            "due_date" => $this->info['Invoice_Due_Date'],
            //            "subtype" => "ship",
            //            "main_nb" => $main_nb,
            //            "prefix" => $prefix,
            //            "job_id" => $this->info['job_id']
            //        );
            //        JV::addTransaction($dat_22, $is_actual);
            
            
        $Invoice_Currency = &$this->info['Invoice_Currency'];
        $second_rate2 = $this->info['second_rate'];
        $lebanon_vat_amount=smc_session()['default_setting']['lebanon_vat_amount'];
        if($Invoice_Currency == '144'){
            $second_rate2 = $lebanon_vat_amount;
        }
        
        $dat_3 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => (!empty(smc_session()['account_setting']['customer_fixed_vat_acc_id']) ? smc_session()['account_setting']['customer_fixed_vat_acc_id'] : $vat_account),
                "Transaction_Type" => "Credit",
                "Transaction_Amount" => $this->info['vat1_total'],
                "Transaction_Date" => $today,
                "Currency_ID" => $this->info['Invoice_Currency'],
                "Logged_ID" => $this->info['Logged_ID'],
                "date_created" => $old_date_created,
                "date_time" => $date_time,
                "created_logged_id" => $old_created_logged_id,
                "Transaction_Description" => $desc,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate2,
                "main_id" => $this->info['Invoice_ID_Auto'],
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $this->info['Invoice_Due_Date'],
                "main_nb" => $main_nb,
                "prefix" => $prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id,
                "subtype" => "vat1"
            ];
            JV::addTransaction($dat_3, $is_actual);

            $dat_3 = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => (!empty(smc_session()['account_setting']['customer_fixed_vat_acc_id']) ? smc_session()['account_setting']['customer_fixed_vat_acc_id'] : $vat_account),
                "Transaction_Type" => "Credit",
                "Transaction_Amount" => $this->info['vat2_total'],
                "Transaction_Date" => $today,
                "Currency_ID" => $this->info['Invoice_Currency'],
                "Logged_ID" => $this->info['Logged_ID'],
                "date_created" => $old_date_created,
                "date_time" => $date_time,
                "created_logged_id" => $old_created_logged_id,
                "Transaction_Description" => $desc,
                "Current_Ex_Rate" => $rate,
                "second_currency_rate" => $second_rate,
                "main_id" => $this->info['Invoice_ID_Auto'],
                "main_type" => "inv",
                "branch_id" => $branch_id,
                "due_date" => $this->info['Invoice_Due_Date'],
                "main_nb" => $main_nb,
                "prefix" => $prefix,
                "user_ref" => $invoice_user_reference,
                "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                "project_id" => $this->info['project_id'],
                "salesman_id" => $sales_id,
                "subtype" => "vat2"
            ];
            JV::addTransaction($dat_3, $is_actual);

            if ($this->info['is_invoice_total_on_shipping'] == 1) {
                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customerAccount,
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => ($this->info['Invoice_Net_Total'] + $this->info['shipping']),
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc . (empty($this->info['customer_branch_name']) ? '' : (' - ' . $this->info['customer_branch_name'])),
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => $pos_customer_id
                ];
                JV::addTransaction($dat_122, $is_actual);

                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $ship_comp_acc_id,
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Invoice_Net_Total'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_122, $is_actual);

                $dat_122 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $this->info['shipping_account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['shipping'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_122, $is_actual);
            }
            if (smc_session()['default_setting']['generate_pay_rec_from_inv_pur'] == 0) {
                $dat_12 = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => ($this->info['is_invoice_total_on_shipping'] == 0 ? $customerAccount : $ship_comp_acc_id),
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $this->info['Invoice_Net_Total'] - $remaining,
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc . ((!empty($this->info['customer_branch_name']) && $this->info['is_invoice_total_on_shipping'] == 0) ? (' - ' . $this->info['customer_branch_name']) : ''),
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => $invoice_user_reference,
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 1 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id,
                    "pos_customer_id" => ($this->info['is_invoice_total_on_shipping'] == 0 ? $pos_customer_id : 0)
                ];
                JV::addTransaction($dat_12, $is_actual);

                $dat_4 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'credit',
                    "Transaction_Account" => $this->info['Card_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Card_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "subtype" => "credit",
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => (!empty($this->info['card_user_ref']) ? $this->info['card_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_4, $is_actual);

                $dat_5 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'cash',
                    "Transaction_Account" => $this->info['Cash_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Cash_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "subtype" => "cash",
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => (!empty($this->info['cash_user_ref']) ? $this->info['cash_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_5, $is_actual);

                $dat_5 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'other',
                    "Transaction_Account" => $this->info['Other_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Other_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "subtype" => "other",
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => (!empty($this->info['other_user_ref']) ? $this->info['other_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_5, $is_actual);

                $dat_6 = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'check',
                    "Transaction_Account" => $this->info['Check_Account'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $this->info['Check_Amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $old_date_created,
                    "date_time" => $date_time,
                    "created_logged_id" => $old_created_logged_id,
                    "Transaction_Description" => $desc,
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $second_rate,
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "branch_id" => $branch_id,
                    "due_date" => (!empty($this->info['check_due_date']) ? $this->info['check_due_date'] : $this->info['Invoice_Due_Date']),
                    "value_date" => (empty($this->info['value_date']) ? '' : $this->info['value_date']),
                    "check_nb" => empty($this->info['Check_Num']) ? '' : $this->info['Check_Num'],
                    "subtype" => "check",
                    "main_nb" => $main_nb,
                    "prefix" => $prefix,
                    "user_ref" => (!empty($this->info['check_user_ref']) ? $this->info['check_user_ref'] : $invoice_user_reference),
                    "job_id" => ($job_trans_type == 0 || $job_trans_type == 2 ? $this->info['job_id'] : 0),
                    "project_id" => $this->info['project_id'],
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($dat_6, $is_actual);
            } else {
                if ($this->info['Cash_Amount'] > 0 || $this->info['Card_Amount'] > 0 || $this->info['Check_Amount'] > 0) {
                    $pay_data = array();
                    $pay_data['Payment_Date'] = $this->info['Invoice_Date'];
                    $pay_data['Status_ID'] = $is_actual;
                    $pay_data['branch_id'] = $branch_id;
                    $pay_data['payment_prefix'] = $prefix;
                    $pay_data['IsReceipt'] = 1;
                    $pay_data['Currency_Rate'] = $rate;
                    $pay_data['Currency_ID'] = $this->info['Invoice_Currency'];
                    $pay_data['date_time'] = $date_time;
                    $pay_data['date_created'] = $date_time;
                    $pay_data['Logged_ID'] = $this->info['Logged_ID'];
                    $pay_data['created_logged_id'] = $this->info['Logged_ID'];
                    $pay_data['Account_Code'] = $customerAccount;
                    $pay_data['job_id'] = $this->info['job_id'];
                    $pay_data['project_id'] = $this->info['project_id'];
                    $pay_data['salesman_id'] = $sales_id;
                    $pay_data['total_payment'] = $payment_paid_amount;
                    $pay_data['payment'] = array();
                    if ($this->info['Card_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Card_Account'],
                            'Payment_Amount' => $this->info['Card_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => '',
                            'Check_Date' => '',
                            'value_date' => '',
                            'user_ref' => (empty($this->info['card_user_ref']) ? '' : $this->info['card_user_ref']),
                        );
                    }
                    if ($this->info['Cash_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Cash_Account'],
                            'Payment_Amount' => $this->info['Cash_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => '',
                            'Check_Date' => '',
                            'value_date' => '',
                            'user_ref' => (empty($this->info['cash_user_ref']) ? '' : $this->info['cash_user_ref']),
                        );
                    }
                    if ($this->info['Check_Amount'] > 0) {
                        $pay_data['payment'][] = array(
                            'is_cheque' => 0,
                            'Payment_Type_ID' => $this->info['Check_Account'],
                            'Payment_Amount' => $this->info['Check_Amount'],
                            'Payment_Note' => $desc,
                            'Check_Number' => (empty($this->info['Check_Num']) ? '' : $this->info['Check_Num']),
                            'Check_Date' => (!empty($this->info['check_due_date']) ? $this->info['check_due_date'] : $this->info['Invoice_Due_Date']),
                            'value_date' => (empty($this->info['value_date']) ? '' : $this->info['value_date']),
                            'user_ref' => (empty($this->info['check_user_ref']) ? '' : $this->info['check_user_ref']),
                        );
                    }
                    $pay_data['close_arr'][] = array(
                        'inv_id' => $this->info['Invoice_ID_Auto'],
                        'inv_amount' => $payment_paid_amount,
                        'inv_currency' => $this->info['Invoice_Currency']
                    );
                    $payment = new Payment();
                    $payment->stop_transaction_start_end = true;
                    $payment->setData($pay_data)->create();
                }
            }
        }
        $arr = ['type' => 'inv', 'main_id' => $this->info['Invoice_ID_Auto'], 'action' => 1, 'date_time' => $date_time,
            'user_id' => $this->info['Logged_ID']];
        CommonFunctions::add_user_log($arr);
        $error = $this->db->error();
        //        echo"<pre>";die(print_r($error));
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
            return ($return_inv_num ? [$this->info['Invoice_ID_Auto'], $invoice_num] : [$this->info['Invoice_ID_Auto']]);
        }else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
            return ($return_inv_num ? [array_unique($error)] : array_unique($error));
        }
        //        return array_unique($error);
    }

    public function getInvoiceByID($id, $from_pos = false) {
        $start = microtime(true);
        $data = array("Main" => array(), "Details" => array(), "Payment" => array());
        $year = SESSION::getCurrentYearID();
        $entry_ids_array = array();
        $entry_ids_str = '';
        $query_main = $this->db->query('select 
        `i`.`r_d_sph` AS `r_d_sph`,
        `i`.`c_d_cyl` AS `c_d_cyl`,
        `i`.`c_d_ax` AS `c_d_ax`,
        `i`.`c_d_sph` AS `c_d_sph`,
        `i`.`l_d_cyl` AS `l_d_cyl`,
        `i`.`l_d_ax` AS `l_d_ax`,
        `i`.`r_r_sph` AS `r_r_sph`,
        `i`.`c_r_cyl` AS `c_r_cyl`,
        `i`.`c_r_ax` AS `c_r_ax`,
        `i`.`c_r_sph` AS `c_r_sph`,
        `i`.`l_r_cyl` AS `l_r_cyl`,
        `i`.`cl_r_sph` AS `cl_r_sph`,
        `i`.`cl_r_cyl` AS `cl_r_cyl`,
        `i`.`cl_r_axis` AS `cl_r_axis`,
        `i`.`cl_r_ipd` AS `cl_r_ipd`,


        `i`.`cl_l_sph` AS `cl_l_sph`,
        `i`.`cl_l_cyl` AS `cl_l_cyl`,
        `i`.`cl_l_axis` AS `cl_l_axis`,
        `i`.`cl_l_ipd` AS `cl_l_ipd`,

        `i`.`supply_date` AS `supply_date`,
        `i`.`driver_id` AS `driver_id`,
        `i`.`from_place` AS `from_place`,
        `i`.`to_place` AS `to_place`,
        i.current_year_id,i.po,i.job_inv,i.project_code ,i.project_name_inv,concat(i.invoice_prefix,i.Invoice_ID) AS ID,
          i.Invoice_ID_Auto AS Auto_ID,i.Invoice_Date AS Date,i.Invoice_Due_Date AS Due_Date,
          i.Invoice_Discount AS Discount,i.discount_amount,i.Invoice_VAT AS VAT,i.Invoice_Sub_Total AS Sub_Total,
          i.Invoice_Net_Total AS Net_Total,
          i.Invoice_Paid_Amount AS Paid_Amount,cu.Currency_ID,cu.Currency_Symbol,cu.Currency_Name, cu.currency_round,
          i.Depot_ID,i.Customer_ID,c.Customer_Name,i.truck,i.invoice_prefix,i.Invoice_Shipping as shipping,
          i.is_main_transfer,i.Class_ID,
          pc.Class_Name,i.pos_customer_id,i.sales_purchase_id,
          concat(`e`.`Employee_FirstName`," ",`e`.`Employee_LastName`) AS Employee_Name,i.Sales_ID,i.Invoice_Description,
          i.Account_ID,pc.is_ttc,
          `c`.`customer_due_date_period` AS due_date_period,i.table_id,co.Account_Code,co.Account_Name,
          i.current_rate,i.job_id,j.job_name,
          i.tax_amount,pc.tax_amount as class_tax,
          i.posponted_type,i.postponed_date_time,i.order_note,i.Is_Delivery,i.postponed_note,dp.Depot_Name,
          i.is_branch_transfer,i.invoice_app_id,i.Delivery_Time,i.project_id,pr.project_name,
          ship_comp.shipping_company_name,
          i.shipping_company_id,i.invoice_user_reference,i.shipping_note,i.subscription_fees_id,
          i.is_invoice_total_on_shipping,i.trans_on_change_status,i.ship_comp_acc_id,i.shipping_note,concat_ws(" - ",c.Customer_Name,contra.contra_date,contra_nb) as contra_name,i.contra_id,
          i.invoice_type,i.reservation_id,i.Invoice_Note,i.customer_name_alias,i.customer_address_alias,
          customer_branches.customer_branch_name,i.customer_branch_id,i.Is_Closed,i.invoice_type_id,i.reason_id,
          ifnull(driver.driver_name,"") as driver_name,i.driver_id ,i.second_currency_rate,
          ifnull(pos_cust.customer_name,"") as pos_customer_name,i.ticketing_id,i.Invoice_Status
          from `tbl_invoices` `i` join `tbl_customers` `c` 
          on `i`.`Customer_ID` = `c`.`Customer_ID` join `tbl_common_currency` `cu` 
          on `cu`.`Currency_ID` = `i`.`Invoice_Currency` left join `tbl_hrm_employee` `e` 
          on `e`.`Employee_ID` = `i`.`Sales_ID` left join `tbl_pricing_class` `pc` 
          on `pc`.`Class_ID` = `i`.`Class_ID`
          join `tbl_chart_of_accounts` `co` 
          on `co`.`Account_ID` = `i`.`Account_ID` join `tbl_stock_depot_warehouse` `dp` 
          on `dp`.`Depot_ID` = `i`.`Depot_ID` left join `tbl_accounting_jobs` `j` 
          on `j`.`job_id` = `i`.`job_id`  left join `tbl_projects` `pr` 
          on `pr`.`project_id` = `i`.`project_id` left join `tbl_shipping_company` `ship_comp` 
          on `ship_comp`.`shipping_company_id` = `i`.`shipping_company_id`
          left join tbl_contra contra on contra.contra_id = i.contra_id
          left join tbl_customer_branches customer_branches on customer_branches.customer_branch_id = i.customer_branch_id
          left join tbl_drivers driver on driver.driver_id = i.driver_id
          left join tbl_pos_customers pos_cust on pos_cust.customer_id = i.pos_customer_id
          where Invoice_ID_Auto = "' . smc_escape($id) . '" and current_year_id = "' . $this->year_id . '"');
        //        $query_main = $this->db->query('select current_year_id,concat(invoice_prefix,Invoice_ID) AS ID,
        //          Invoice_ID_Auto AS Auto_ID,Invoice_Date AS Date,Invoice_Due_Date AS Due_Date,Invoice_Discount AS Discount,
        //          discount_amount,Invoice_VAT AS VAT,Invoice_Sub_Total AS Sub_Total,Invoice_Net_Total AS Net_Total,
        //          Invoice_Paid_Amount AS Paid_Amount,Currency_ID,Currency_Symbol,Currency_Name, currency_round,Depot_ID,
        //          Customer_ID,Customer_Name,truck,invoice_prefix,Invoice_Shipping as shipping,is_main_transfer,Class_ID,
        //          Class_Name,pos_customer_id,sales_purchase_id,Employee_Name,Sales_ID,Invoice_Description,Account_ID,is_ttc,
        //          due_date_period,table_id,Account_Code,Account_Name,current_rate,job_id,job_name,tax_amount,class_tax,
        //          posponted_type,postponed_date_time,order_note,Is_Delivery,postponed_note,Depot_Name,
        //          is_branch_transfer,invoice_app_id,Delivery_Time,project_id,project_name,shipping_company_name,
        //          shipping_company_id,invoice_user_reference,shipping_note,subscription_fees_id,
        //          is_invoice_total_on_shipping,ship_comp_acc_id
        //          from invoice_list_main where Invoice_ID_Auto = "' . smc_escape($id) . '" and current_year_id = "' . $this->year_id . '"');
        $row = $this->db->assoc($query_main);
        $data['Main'] = $row;
        $data['Main']['shipping_account'] = '';
        $data['Main']['shipping_id'] = '';
        $data['Main']['shipping_name'] = '';
        //
        $query_transfer = $this->db->query('select * from tbl_stock_request where invoice_auto_id = "' . smc_escape($id) . '"');
        $row_trans = $this->db->rowsno($query_transfer);
        $data['Main']['inv_transfered'] = !empty($row_trans) ? 1 : 0;
        //
        if (!empty($row)) {
            $ship_query = $this->db->query('select * from tbl_delivery_fees where delivery_fees_amount = "' . $data['Main']['shipping'] . '"');
            $ship_data = $this->db->assoc($ship_query);
            $data['Main']['delivery_fees_view'] = empty($ship_data['delivery_fees_view']) ? $ship_data['delivery_fees_amount'] : $ship_data['delivery_fees_view'];
            $ref = "Inv." . $id;
            $acc_query = $this->db->query("SELECT 
                                            p.Account_Name,
                                            p.Account_Code,
                                            p.Account_ID,
                                             t.Transaction_Reference
                                        FROM 
                                            tbl_accounting_transactions t
                                        inner JOIN 
                                            tbl_chart_of_accounts p
                                        ON 
                                            t.Account_ID = p.Account_ID
                                       WHERE 
                                            t.main_id = '" . $id . "'
                                        AND 
                                            t.main_type = 'inv'
                                        AND 
                                           t.Transaction_Reference = 'ship'
                                        ");
            while ($acc_row = $this->db->assoc($acc_query)) {
                $data['Main']['shipping_account'] = $acc_row['Account_Code'];
                $data['Main']['shipping_id'] = $acc_row['Account_ID'];
                $data['Main']['shipping_name'] = $acc_row['Account_Name'];
            }
            if ($from_pos && !empty($data['Main']['pos_customer_id'])) {
                $data['Person'] = Customer::getPOSCustomerByID($data['Main']['pos_customer_id']);
            } else {
                $data['Person'] = Customer::getCustomerByID($data['Main']['Customer_ID']);
                if (!empty($data['Main']['pos_customer_id'])) {
                    $pos_cust = Customer::getPOSCustomerByID($data['Main']['pos_customer_id']);
                    $data['Person']['Name'] = $data['Person']['Name'] . ' - ' . $pos_cust['Name'];
                }
            }
            $data['Person']['other_pay_acc_id'] = !isset($data['Person']['other_pay_acc_id']) ? 0 : $data['Person']['other_pay_acc_id'];
            $last_price_arr = array();
            //                        echo"<pre>";die(print_r($data['Main']));
            if (!is_null($data['Main']['Customer_ID']) && (($this->permissions->hasPermission('view_sales_last_price') && !$from_pos) || ($from_pos && $this->permissions->hasPermission('view_last_price_pos')))) {
                $product_ids = array();
                $prod_query = $this->db->query('select distinct Product_ID 
                from tbl_invoice_products_details where Invoice_ID_Auto = "' . $id . '"');
                while ($row = $this->db->assoc($prod_query)) {
                    $product_ids[] = $row['Product_ID'];
                }
                if (!empty($product_ids))
                    $last_price_arr = CommonBusiness::viewLastProductCustomerClassPrice($product_ids, $data['Main']['Customer_ID'], $data['Main']['Class_ID']);
            }
            //            echo"<pre>";die(print_r($last_price_arr));
            //echo(microtime(true) - $start).'===';
            $data['item_loc'] = array();
            $query_details = $this->db->query('select
                                                i.Entery_ID AS Entery_ID,
                                                i.from_time AS from_time,
                                                i.to_time AS to_time,
                                                i.modify_date AS modify_date,
                                                i.driver_id AS driver_id,
                                                i.n_height AS n_height,
                                                i.n_width AS n_width,
                                                i.n_total AS n_total,
                                                i.qty_link AS qty_link,
                                                i.is_collected_points AS is_collected_points,

                                                p.Invoice_ID_Auto AS Invoice_ID_Auto,
                                                i.Item_Quantity_Current AS Item_Quantity_Current,
                                                ps.Product_Code AS Code,
                                                ps.Product_Name AS Name,
                                                ps.Product_Limit_Discount,
                                                ps.is_tax,ps.is_lot,ps.is_serial,ps.is_service,
                                                ps.Status_ID,
                                                if(i.vat_percent <> 0,1,0) AS VAT,
                                                (( if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity) /uc.conversion_amount)+ i.Item_Quantity_Current) as Product_Quantity,
                                                (( if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)/uc.conversion_amount)+i.Item_Quantity_Current) AS Quantity,
                                                i.Product_ID AS Product_ID,
                                                i.vat_percent,i.vat2_percent,
                                                i.vat_amount,i.vat2_amount,
                                                i.unit_cost,
                                                i.product_description,
                                                uc.Bar_Code,
                                                i.Product_Discount AS Product_Discount,
                                                i.Product_Net_Price AS Product_Net_Price,
                                                i.Product_Total_Price AS Product_Total_Price,
                                                (i.Product_Quantity/i.Item_Quantity_Current) AS uom_con,
                                                 i.UOM_ID,ps.is_expiry,i.expiry_date,"" as cost_percent,
                                                 ps.force_change_price,i.vehicle_id,v.Vehicle_Code,v.Vehicle_Name,
                                                 concat_ws(" ",e.Employee_FirstName,e.Employee_MiddleName,e.Employee_LastName) as Employee_Name,
                                                 i.commission,i.depot_id,w.Depot_Code,w.Depot_Name,e.employee_id,
                                                 ps.Category_ID,i.reserve_from,i.reserve_to,ps.duration_reservation,
                                                 (i.total_tax/i.Item_Quantity_Current) as unit_tax,
                                                 i.total_tax,i.serial_nb,i.lot_nb,i.Delivery_Report_ID,ps.recipe_qty,
                                                 i.date_created as details_date_created,i.hold,i.Product_Quantity as def_in_qty,l.Product_Depot_Quantity as depot_qty
                                            from 
                                                tbl_invoice_products_details i 
                                            inner join 
                                                tbl_invoices p 
                                            on
                                                p.Invoice_ID_Auto = i.Invoice_ID_Auto
                                            inner JOIN
                                                uom_conversions uc
                                            ON 
                                                uc.Product_ID = i.Product_ID
                                            and 
                                                i.UOM_ID = uc.uom_from
                                            inner join 
                                                tbl_stock_products ps 
                                            on
                                                ps.Product_ID = i.Product_ID
                                            left  join
                                                tbl_stock_product_location l
                                            on 
                                                l.Location_Product_ID = i.Product_ID 
                                            and 
                                                l.Product_Depot_ID = i.depot_id
                                            left join tbl_garage_vehicle v on v.Vehicle_ID = i.vehicle_id
                                            left join tbl_hrm_employee e on e.Employee_ID = i.employee_id
                                            inner join tbl_stock_depot_warehouse w on w.Depot_ID = i.depot_id
                                            where
                                                p.current_year_id = "' . $year . '"
                                            and 
                                                p.Invoice_ID_Auto = "' . $id . '"
                                            order by p.Invoice_ID');
            $product_entry_ids = array();
            //            $product_ids = array();
            while ($row = $this->db->assoc($query_details)) {
                if (empty($data['item_loc'][$row['Product_ID']][$row['depot_id']]))
                    $data['item_loc'][$row['Product_ID']][$row['depot_id']] = 0;
                $data['item_loc'][$row['Product_ID']][$row['depot_id']] += $row['def_in_qty'];

                $product_entry_ids[$row['Product_ID']][] = $row['Entery_ID'];
                //                $product_ids[] = $row['Product_ID'];
                $row['ttc_price'] = $row['Product_Net_Price'] * (1 + ($row['vat_percent'] / 100));
                $row['ttc_price'] = $row['ttc_price'] * (1 + ($row['vat2_percent'] / 100));
                $row['Product_UOM'] = '';
                $last_cost = CommonBusiness::viewLastProductCost($row["Product_ID"]) * $row['uom_con'];
                $row['LAST_COST'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $data['Main']['Currency_ID'], $last_cost);
                $last_price = 0;
                //                           echo(microtime(true) - $start).'____';
                if (array_key_exists($row['Product_ID'], $last_price_arr)) {
                    //                    $last_price = CommonBusiness::viewLastProductCustomerClassPrice($row["Product_ID"], $data['Main']['Customer_ID'], $data['Main']['Class_ID']);
                    $last_price = $last_price_arr[$row['Product_ID']];
                }
                //                              echo(microtime(true) - $start).'____<br/>';
                $row['last_price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $data['Main']['Currency_ID'], $last_price);
                $row['has_option'] = 0;
                $row['options'] = array();
                $data['Details'][$row['Entery_ID']] = $row;
                $entry_ids_array[] = $row['Entery_ID'];
            }
            if (!empty($entry_ids_array)) {
                $entry_ids_str = implode(',', $entry_ids_array);
                $query = $this->db->query('select option_id,product_id,
                    UOM_ID as uom_id,option_quantity as qty,invoice_detail_id from tbl_invoice_product_options 
                    where invoice_detail_id in (' . $entry_ids_str . ')');
                while ($op_row = $this->db->assoc($query)) {
                    $data['Details'][$op_row['invoice_detail_id']]['options'][] = $op_row;
                    $data['Details'][$op_row['invoice_detail_id']]['has_option'] = 1;
                }


                //            echo(microtime(true) - $start).'===';
                $uom_products_query = $this->db->query('select uom_from,Product_ID from tbl_uom_conversions where Product_ID IN (' . implode(',', array_keys($product_entry_ids)) . ') ');
                while ($uom_row = $this->db->assoc($uom_products_query)) {
                    foreach ($product_entry_ids[$uom_row['Product_ID']] as $entry_id) {
                        if ($data['Details'][$entry_id]['Product_UOM'] != '')
                            $data['Details'][$entry_id]['Product_UOM'] .= '/';
                        $data['Details'][$entry_id]['Product_UOM'] .= $uom_row['uom_from'];
                    }
                }


                $criteria_details_query = $this->db->query('select  inv_details.Entery_ID,
                                                            crit_details.criteria_detail_id,
                                                            crit_details.criteria_detail_name, 
                                                            inv_details.criteria_price, 
                                                            inv_details.criteria_note,
                                                            crit_details.criteria_id
                                                    from tbl_invoice_product_criteria inv_details
                                                    inner join tbl_product_criteria_detail crit_details
                                                    using(criteria_detail_id)
                                                    where inv_details.Entery_ID IN (' . $entry_ids_str . ')
                                                    ');
                while ($row = $this->db->assoc($criteria_details_query)) {
                    $data['Details'][$row['Entery_ID']]['criteria'][] = $row;
                }
                $add_ons_details_query = $this->db->query('select prod_add_ons.Entery_ID,
                                                          add_ons.add_ons_details_id,
                                                          concat(add_ons.add_ons_details_title," (",prod_add_ons.Quantity,") ") as details
                                                   from  tbl_invoice_product_add_ons prod_add_ons
                                                   inner join tbl_add_ons_details add_ons
                                                   using(add_ons_details_id)
                                                   where prod_add_ons.Entery_ID IN (' . $entry_ids_str . ')
        ');
                while ($row_add_ons = $this->db->assoc($add_ons_details_query)) {
                    $data['Details'][$row['Entery_ID']]['add_ons'][] = $row_add_ons;
                }
                $data['Details'] = array_values($data['Details']);
            }
            $query = $this->db->query("SELECT 
                                            t.Transaction_Amount,
                                            t.Transaction_Reference,
                                            t.Account_ID,
                                            p.Account_Name AS P_Name,
                                            t.check_nb,t.due_date,t.value_date,t.user_ref,
                                             t.Transaction_Description
                                        FROM 
                                            tbl_accounting_transactions t
                                        inner JOIN 
                                            tbl_chart_of_accounts p
                                        ON 
                                            t.Account_ID = p.Account_ID
                                       WHERE 
                                             t.main_id = '" . $id . "'
                                        AND 
                                            t.main_type = 'inv'
                                        AND 
                                            t.Transaction_Reference in ('cash','check','credit','other')
                                        ");
            while ($row = $this->db->assoc($query)) {
                if (stripos($row['Transaction_Reference'], 'cash') !== false)
                    $data['Payment']['Cash'] = $row;
                if (stripos($row['Transaction_Reference'], 'check') !== false) {
                    $data['Payment']['Cheque'] = $row;
                }
                if (stripos($row['Transaction_Reference'], 'credit') !== false)
                    $data['Payment']['Credit_Card'] = $row;
                if (stripos($row['Transaction_Reference'], 'other') !== false)
                    $data['Payment']['others'] = $row;
            }
        }

        $data['pay_inv_link'] = '';
        $query = $this->db->query('SELECT concat_ws("",p.prefix,p.pay_rec_nb) as pay_nb 
            FROM `tbl_invoice_payments` i join tbl_payment_receipt p on p.pay_rec_id = i.`record_id`
            where i.inv_pur_id = "' . $id . '" and i.type in ("rec","cmjv","cre")');
        while ($row = $this->db->assoc($query)) {
            $data['pay_inv_link'] = empty($data['pay_inv_link']) ? $row['pay_nb'] : ',' . $row['pay_nb'];
        }
        //        echo(microtime(true) - $start).'===';
        //        die();
        //                echo"<pre>";die(print_r($data));
        return $data;
    }

    public function getPendingInvoices() {
        $data = array();
        $query = $this->db->query('select concat(Customer_Name," - ",Invoice_ID) as invoice, Invoice_ID_Auto as id from tbl_invoices left join tbl_customers USING(Customer_ID) where Invoice_Status = 3');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getTotalItemProfit() {
        $condition = '';
        $data = array();
        if (!empty($this->info['from_date']) && !empty($this->info['to_date']))
            $condition .= ' AND Date between "' . $this->info['from_date'] . '" and "' . $this->info['to_date'] . '"';
        
         if (!empty($this->info['search_branch_id']))
            $condition .= ' AND branch_id = ' . $this->info['search_branch_id'] . ' ';
         if (!empty($this->info['cat_id']))
            $condition .= ' AND Category_ID in(' . $this->info['cat_id'] . ')';
        if (!empty($this->info['product_id']))
            $condition .= ' AND Product_ID = "' . $this->info['product_id'] . '"';
        if (isset($this->info['person_id']) && $this->info['person_id'] != '')
            $condition .= ' AND Customer_ID = "' . $this->info['person_id'] . '"';
        if (empty($this->info['is_actual']))
            $condition .= ' AND is_actual = 0';
        if (!empty($this->info['brand_id']))
            $condition .= ' AND brand_id = "' . $this->info['brand_id'] . '"';
        if (!empty($this->info['zero_price']))
            $condition .= ' AND Product_Total_Price = 0';
        if (!empty($this->info['Invoice_ID_Auto']))
            $condition .= ' AND Invoice_ID_Auto = "' . $this->info['Invoice_ID_Auto'] . '"';
        $data = ['total_cost' => 0, 'total_price' => 0,
            'second_total_cost' => 0, 'second_total_price' => 0,
            'profit' => 0, 'second_profit' => 0, 'profit_percent' => 0];
        $table = '';
        if (empty($this->info['with_return'])) {
            $table = 'product_mov_invoice';
        } else {
            $table = '(select Product_Name,u.*,um.UOM_Name,uc.UOM_Name as current_uom_name,
            p.Product_Name as Item_Name,p.Product_Code as Code,c.Currency_Symbol,p.Category_ID,(Quantity/if(p.default_view_uom_id=0,1,p.default_view_rate)) as def_view_qty from
            (select i.Customer_ID as Customer_ID,`d`.`Product_ID`,`d`.`Product_Quantity` AS `Quantity`,`d`.`Product_Total_Price`AS `Product_Total_Price`,
            `i`.`date_created` ,i.Invoice_Date as Date,`i`.`Invoice_Currency` AS `Currency_ID`,i.current_year_id,i.Logged_ID ,
            i.created_logged_id,i.is_actual,i.branch_id,i.customer_branch_id ,d.vat_amount,d.vat2_amount,
            d.Item_Quantity_Current,`d`.`unit_cost` AS `Product_Cost`,d.total_tax,d.UOM_ID as current_uom_id,i.is_committed,d.Entery_ID,
            (`d`.`Product_Total_Price` - (`d`.`Product_Quantity` * `d`.`unit_cost`)) AS `profit`,0 as is_return,
            (((`d`.`Product_Total_Price` - (`d`.`Product_Quantity` * `d`.`unit_cost`)) / `d`.`Product_Total_Price`) * 100) AS `profit_percent`,
            i.current_rate,i.second_currency_rate
            from `tbl_invoice_products_details` `d` 
            join `tbl_invoices` `i` on `i`.`Invoice_ID_Auto` = `d`.`Invoice_ID_Auto` 
            join `tbl_stock_uom` `uc` on((`uc`.`UOM_ID` = `d`.`UOM_ID`))
            where i.is_committed = 1
            union all
            select i.Person_ID as Customer_ID,d.Product_ID,(d.Return_Product_Quantity *(-1)) as Quantity,
            (d.Return_Product_Total  * -1) as Product_Total_Price,i.date_created ,i.Return_Invoice_Date as Date,i.Currency_ID,i.current_year_id,
            i.Logged_ID,i.created_logged_id,i.Is_Actual as is_actual,i.branch_id,i.customer_branch_id ,(d.vat_amount  * -1) as vat_amount,(d.vat2_amount  * -1) as vat2_amount,
            d.Item_Quantity_Current,`d`.`unit_cost` AS `Product_Cost`,0 as total_tax,d.UOM_ID as current_uom_id,1 as is_committed,d.Return_Item_ID as Entery_ID,
            ((`d`.`Return_Product_Total` - (`d`.`Return_Product_Quantity` * `d`.`unit_cost`))*-1) AS `profit`,1 as is_return,
            ((((`d`.`Return_Product_Total` - (`d`.`Return_Product_Quantity` * `d`.`unit_cost`)) / `d`.`Return_Product_Total`) * 100)*-1) AS `profit_percent`,
            i.current_rate,i.second_currency_rate
            from tbl_accounting_return_items d join tbl_accounting_return_invoices i 
            on d.Return_Invoice_ID = i.Return_Invoice_ID) u join tbl_stock_products p on u.Product_ID = p.Product_ID 
            join tbl_common_currency c on c.Currency_ID = u.Currency_ID left join tbl_stock_uom um 
            on um.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)
            join `tbl_stock_uom` `uc` on((`uc`.`UOM_ID` = `u`.`current_uom_id`))
            ) as movement';
        }
        if (empty($this->info['cost_type'])) {
            $query = $this->db->query('Select sum(Product_Cost*Quantity*current_rate) as total_cost,
                                        sum(Product_Cost*Quantity*second_currency_rate) as second_total_cost,
                                        sum(Product_Total_Price*current_rate) as total_price,
                                        sum(Product_Total_Price*second_currency_rate) as second_total_price
                               from ' . $table . ' where 1=1  and is_committed = 1' . $condition);
            $row = $this->db->assoc($query);
            if (!is_null($row['total_cost'])) {
                $data['total_cost'] = $row['total_cost'];
                $data['second_total_cost'] = $row['second_total_cost'];
                $data['total_price'] = $row['total_price'];
                $data['second_total_price'] = $row['second_total_price'];
                $data['profit'] = $row['total_price'] - $row['total_cost'];
                $data['second_profit'] = $row['second_total_price'] - $row['second_total_cost'];
                $data['profit_percent'] = (!empty($row['total_cost']) ? (($data['profit'] / $row['total_cost']) * 100) : 0);
            }
        } else {
            $group_cond = '';
            if (!empty($this->info['is_group']))
                $group_cond .= ' group by Product_ID ';
            $query = $this->db->query('Select Product_ID,' . (!empty($this->info['is_group']) ? 'sum(Quantity)' : '(Quantity)') . ' as total_qty,
                                        ' . (!empty($this->info['is_group']) ? 'sum(Product_Total_Price*current_rate)' : '(Product_Total_Price*current_rate)') . ' as total_price,
                                        ' . (!empty($this->info['is_group']) ? 'sum(Product_Total_Price*second_currency_rate)' : '(Product_Total_Price*second_currency_rate)') . ' as second_total_price
                               from ' . $table . '  where 1=1  and is_committed = 1' . $condition . ' ' . $group_cond);
            while ($row = $this->db->assoc($query)) {
                $cost = 0;
                if ($this->info['cost_type'] == 1) {
                    $cost = CommonBusiness::viewCostByAverage([$row['Product_ID']], true)[$row['Product_ID']] * $row['total_qty'];
                } else {
                    $cost = CommonBusiness::viewLastProductCost($row['Product_ID']) * $row['total_qty'];
                }
                $sec_cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], smc_session()['default_setting']['second_currency'], $cost);

                //                echo $cost
                $data['total_cost'] += $cost;
                $data['second_total_cost'] += $sec_cost;
                $data['total_price'] += $row['total_price'];
                $data['second_total_price'] += $row['second_total_price'];
                $data['profit'] += ($row['total_price'] - $cost);
                $data['second_profit'] += ($row['second_total_price'] - $sec_cost);
                $data['profit_percent'] = $data['total_cost'] == 0 ? 0 : ($data['profit'] / $data['total_cost'] * 100);
            }
        }
        return $data;
    }

    public function searchInvTruck($term) {
        $data = array();
        $query = $this->db->query('select distinct truck , truck as text from tbl_invoices
            where truck like "%' . smc_escape($term) . '%"  and truck <> "" limit 30');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    /**
     * when change in this ft. make sure that end of day/shift & user invoice report is still working..
     */
    public function totalUserInvoices($date_from, $date_to, $user_id = 0, $salesman = 0, $is_actual = 0) {
        $data = array();
        $total = 0.0;
        $total_cash = 0.0;
        $total_cash_receipt = 0.0;
        $discount = 0.0;
        $local_currency = CurrencyFactory::returnLocalCurrency();
        //    $local_sym = CurrencyFactory::getLocalCurrencySymbol();
        $cond = '';
        if ($user_id != 0) {
            $cond .= 'and user = "' . $user_id . '"';
        }
        if ($salesman != 0) {
            $cond .= 'and Sales_ID = "' . $salesman . '"';
        }
        if (!empty($this->info['branch_id']))
            $cond .= 'and branch_id = "' . $this->info['branch_id'] . '"';
        if (!empty($this->info['created_by']))
            $cond .= 'and created_logged_id = "' . $this->info['created_by'] . '"';
        if (isset($this->info['customer_id']) && is_numeric($this->info['customer_id'])) {
            $cond .= ' AND current_customer_id ="' . $this->info['customer_id'] . '"';
            if (!empty($this->info['customer_branch_id']))
                $cond .= ' AND customer_branch_id ="' . $this->info['customer_branch_id'] . '"';
        }
        if (!empty($this->info['shipping_company_id'])) {
            $cond .= ' AND shipping_company_id ="' . $this->info['shipping_company_id'] . '"';
        }
        if (!empty($this->info['shipping_status_id'])) {
            $cond .= ' AND shipping_status_id ="' . $this->info['shipping_status_id'] . '"';
        }
        if (!empty($this->info['pick_up_from_date']) && !empty($this->info['pick_up_to_date'])) {
            $cond .= ' and pick_up_date between "' . $this->info['pick_up_from_date'] . '" AND  "' . $this->info['pick_up_to_date'] . '"';
        }
        if (!empty($this->info['drop_off_from_date']) && !empty($this->info['drop_off_to_date'])) {
            $cond .= ' and drop_off_date between "' . $this->info['drop_off_from_date'] . '" AND  "' . $this->info['drop_off_to_date'] . '"';
        }
        if (!empty($this->info['invoice_from_date']) && !empty($this->info['invoice_to_date'])) {
            $cond .= ' and inv_date between "' . $this->info['invoice_from_date'] . '" AND  "' . $this->info['invoice_to_date'] . '"';
        }
        if ($is_actual == 0) {
            $cond .= ' and is_actual = 0 ';
        }


        $query = $this->db->query('select * from user_invoices  where 
          "' . $date_from . '" <= date_created
         and "' . $date_to . '" >= date_created
         and is_committed = 1
        ' . $cond);
        $total_var = empty($this->info['exclude_shipping']) ? 'total' : 'total_no_shipping';
        while ($row = $this->db->assoc($query)) {
            if ($row['type'] == 'Invoice') {
                $total += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row[$total_var]);
                $total_cash += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row['total_cash']);
                $total_cash_receipt += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row['total_cash_receipt']);
                $discount += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row['discount']);
            } else {
                $total -= CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row[$total_var]);
                $total_cash -= CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row['total_cash']);
                $total_cash_receipt -= CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['currency'], $local_currency, $row['total_cash_receipt']);
            }
        }
        $data['total'] = $total;
        $data['total_cash'] = $total_cash + (empty($this->info['include_receipt_payment']) ? 0 : $total_cash_receipt );
        $data['discount'] = $discount;
        return $data;
    }

    public static function getUnpaidInvoicesByCustomer($account, $currency, $pay_id = null, $is_actual = 0, $pos_customer = 0, $type = 'rec') {
        $db = DBConnectorFactory::loadDriver();
        $cust_query = $db->query('select main_id,main_type from
                            tbl_chart_of_accounts
                            where Account_ID = "' . $account . '" ');
        $crow = $db->assoc($cust_query);
        $cid = $crow['main_id'];
        $ctype = $crow['main_type'];
        $data = array();
        $local_currency = CurrencyFactory::returnLocalCurrency();
        //$pay_rate = CurrencyFactory::getLastExRate($currency);
        $fields = ' ';
        $cond = ' ';
        $where_cond = ' ';
        if (!empty($pos_customer)) {
            $cond .= ' and i.pos_customer_id="' . $pos_customer . '" ';
        }
        if (!empty($pay_id)) {
            $fields .= ' if(isnull(p.Payment_Amount),0,p.Payment_Amount) as inv_pay_amount, ';
            $cond .= ' left join tbl_invoice_payments p on i.Invoice_ID_Auto = p.inv_pur_id and p.type = "' . $type . '"
                and p.record_id in(' . $pay_id . ') ';
        }
        if ($is_actual == 0) {
            $where_cond .= ' and is_actual = 0';
        }

        $query = $db->query('select   
                                    i.Invoice_ID_Auto,
                                    concat(i.invoice_prefix,i.Invoice_ID) as Invoice_ID,
                                    i.Invoice_Date, 
                                    i.current_rate,i.second_currency_rate,
                                    i.Invoice_Currency,
                                    i.Invoice_Net_Total,
                                    ' . $fields . '
                                    (i.Invoice_Paid_Amount + i.Payment_Paid_Amount-i.return_paid_amount) as Paid_Amount,
                                    ((i.Invoice_Net_Total+if((i.is_invoice_total_on_shipping=0  and trans_on_change_status=0),i.Invoice_Shipping,0)) - i.Invoice_Paid_Amount - i.Payment_Paid_Amount-i.Return_Invoice_Total+i.return_paid_amount) as Remaining_Amount,
                                    cust.Customer_Name
                                from 
                                    tbl_invoices i
                                inner join tbl_customers cust on cust.Customer_ID = i.Customer_ID    
                                    ' . $cond . '
                                where
                                   (( ((i.Invoice_Net_Total+i.Invoice_Shipping) - i.Invoice_Paid_Amount - i.Payment_Paid_Amount-i.Return_Invoice_Total+i.return_paid_amount) > 0 ' . (empty($pay_id) ? '' : ' || !isnull(Payment_Invoice_ID) ') . ')
                                and i.Customer_ID = "' . $cid . '" and "' . $ctype . '"="cust" and i.is_invoice_total_on_shipping=0)
                                    or 
                                    (( ((i.Invoice_Net_Total) - i.Invoice_Paid_Amount - i.Payment_Paid_Amount-i.Return_Invoice_Total+i.return_paid_amount) > 0 ' . (empty($pay_id) ? '' : ' || !isnull(Payment_Invoice_ID) ') . ')
                                and i.ship_comp_acc_id = "' . $account . '" and (i.is_invoice_total_on_shipping=1 or trans_on_change_status=1))
            ' . $where_cond);
        while ($row = $db->assoc($query)) {
            $row['remaining_local'] = $row['Remaining_Amount'] * $row['current_rate'];
            if ($row['Invoice_Currency'] != $currency) {
                if ($currency == $local_currency) {
                    $row['Invoice_Net_Total'] = $row['Invoice_Net_Total'] * $row['current_rate'];
                    $row['Paid_Amount'] = $row['Paid_Amount'] * $row['current_rate'];
                    $row['Remaining_Amount'] = $row['Remaining_Amount'] * $row['current_rate'];
                } else if ($currency == smc_session()['default_setting']['second_currency']) {
                    $row['Invoice_Net_Total'] = $row['Invoice_Net_Total'] * $row['second_currency_rate'];
                    $row['Paid_Amount'] = $row['Paid_Amount'] * $row['second_currency_rate'];
                    $row['Remaining_Amount'] = $row['Remaining_Amount'] * $row['second_currency_rate'];
                } else {
                    $pay_rate = CurrencyFactory::getCurrencyTimeExchangeRate($currency, $local_currency, $row['Invoice_Date']);
                    $row['Invoice_Net_Total'] = ($row['Invoice_Net_Total'] * $row['current_rate']) / $pay_rate;
                    $row['Paid_Amount'] = ($row['Paid_Amount'] * $row['current_rate']) / $pay_rate;
                    $row['Remaining_Amount'] = ($row['Remaining_Amount'] * $row['current_rate']) / $pay_rate;
                }
            }

            $data[] = $row;
        }
        //        die(print_r($data));
        return $data;
    }

    public function checkInvoicesPayments($id, $is_sales) {
        $data = array();
        $pay_arr = array();
        $pay_query = $this->db->query('select * from tbl_invoice_payments where inv_pur_id = "' . $id . '" and type in (' . ($is_sales ? '"rec","cmjv","cre"' : '"pay","smjv","deb"') . ')');
        while ($row = $this->db->assoc($pay_query)) {
            $pay_arr[] = $row['record_id'];
        }
        if (!empty($pay_arr)) {
            $pay_ids = implode(',', $pay_arr);
            $query = $this->db->query('select concat(prefix,pay_rec_nb) as pid from tbl_payment_receipt where pay_rec_id in (' . $pay_ids . ')');
            while ($pay_row = $this->db->assoc($query)) {
                if (!in_array($pay_row['pid'], $data)) {
                    $data[] = $pay_row['pid'];
                }
            }
        }
        return $data;
    }

    public function updateLinkQuantities($data, $method, $operation) {
        //        $link_qty = $link['quantity'] * $ProductQuantity;
        $cost = CommonBusiness::addCostByType($data, $method);
        if ($data['is_service'] != 1) {
            $up_quan = [&$data['Quantity'], &$data['Product_ID']];
            $this->db->prepare_Stmt("UPDATE 
                                                tbl_stock_products 
                                        SET 
                                                Product_Quantity = Product_Quantity " . $operation . " ?
                                        WHERE 
                                                Product_ID = ? 
                                    ", $up_quan);
            $sub_qty = $operation == '+' ? $data['Quantity'] : $data['Quantity'] * (-1);
            //        echo $operation.'<br>';
            //        $sub_qty = $data['Quantity'] ;
            $dep_dat = [&$data['depot_id'], &$data['Product_ID'], &$sub_qty, &$data['Quantity']];
            //        echo $operation.' =='.$data['Quantity'].'<br>';
            //        die();
            $this->db->prepare_Stmt("insert into  
                                            tbl_stock_product_location 
                                            (Product_Depot_ID,Location_Product_ID,Product_Depot_Quantity)
                                            values (?,?,?)
                                            on duplicate key update
                                            Product_Depot_Quantity = Product_Depot_Quantity " . $operation . " ?
                                    ", $dep_dat);
        }
        return $cost;
    }

    public function invoiceFileData($file_id) {
        $query = $this->db->query('SELECT file_name FROM tbl_app_file_main_data WHERE file_id = "' . $file_id . '"');
        $row = $this->db->assoc($query);
        $path_name = $row['file_name'];
        $path = appFiles . $path_name;
        $first = file_get_contents($path);
        $result = json_decode($first, true);
        //        $data['stock_id'] = 1;
        //        $data['currency_id'] = $result['currency_id'];
        $products = $result['data'];
        //        echo"<pre>";
        //        die(print_r($products));
        $data['products'] = array();
        foreach ($products as $product) {
            $query_details = $this->db->query('select
                                                "' . $product['quantity'] . '" AS Item_Quantity_Current,
                                                ps.Product_Code AS Code,
                                                ps.Product_Name AS Name,
                                                ps.Product_VAT AS VAT,
                                                ps.Product_Quantity,
                                                ps.Product_Limit_Discount,
                                                ps.is_tax,ps.is_service,
                                                uc.Product_ID AS Product_ID,
                                                uc.Bar_Code,
                                                ps.vat_percent,
                                                c.Cat_ID,
                                                c.Cat_Name,
                                                0 as vat_amount,
                                                0 as Product_Discount,
                                                "" as product_description,"" as expiry_date,ps.is_expiry,
                                                "' . $product['price'] . '" AS Product_Net_Price,
                                                ("' . $product['price'] . '"*"' . $product['quantity'] . '") AS Product_Total_Price,
                                                uc.conversion_amount AS uom_con,
                                                uc.uom_to as UOM_ID,
                                                GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                                ps.Status_ID
                                            from 
                                                uom_conversions uc
                                            join 
                                                tbl_stock_products ps 
                                            on
                                                ps.Product_ID = uc.Product_ID
                                                join tbl_product_cat c
                                        on c.Cat_ID = ps.Category_ID
                                            where
                                            uc.Product_ID = "' . $product['id'] . '"
                                                and uc.uom_from = "' . $product['uom_id'] . '"
                                                    group by uc.Product_ID
                                            ');
            $row = $this->db->assoc($query_details);
            $row['unit_cost'] = CommonBusiness::viewCurrentProductCost($row['Product_ID']);
            $data['products'][] = $row;
        }
        return $data;
    }

    public function export_invoices($from, $to, $is_actual) {
        //        $data = array();
        $objPHPExcel = new PHPExcel();
        $cond = ' ';
        if ($is_actual == 0) {
            $cond .= ' and i.is_actual = 0 ';
        }
        // Set the active Excel worksheet to sheet 0
        $objPHPExcel->setActiveSheetIndex(0);
        $rowCount = 1;
        $header_arr = ['Invonum', 'InvoiceDate', 'AccountNum', 'Total', 'Name', 'Accountnum2', 'Currency', 'Rate', 'Exchange', 'Address', 'AccnameX2'];
        $excel_header = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
        for ($i = 0; $i < count($excel_header); $i++) {
            $objPHPExcel->getActiveSheet()->SetCellValue($excel_header[$i] . $rowCount, $header_arr[$i]);
        }
        $rowCount++;
        // we put 53110011 as customer account in case of cash customer only for beauty house
        $inv_main_query = $this->db->query('select concat(i.invoice_prefix,i.Invoice_ID) as Invonum, 
            DATE_FORMAT(i.Invoice_Date, "%d-%b-%y") as InvoiceDate,if(i.Customer_ID=0,53110011,c.Account_Code) as AccountNum,
            i.Invoice_Sub_Total as Total,cust.Customer_Name as Name,coa.Account_Code as Accountnum2,
            cu.Currency_Symbol as Currency,i.current_rate as Rate,
            (i.Invoice_Sub_Total * i.current_rate) as Exchange,cust.Customer_Address as Address,coa.Account_Name as AccnameX2
                from tbl_invoices i
                join tbl_chart_of_accounts c on i.Customer_ID = c.main_id and c.main_type = "cust" and c.sub_type="main"
                join tbl_customers cust on cust.Customer_ID = i.Customer_ID
                join tbl_chart_of_accounts coa on coa.Account_ID = i.Account_ID
                join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency
                where 
                i.Invoice_Date between "' . $from . '" and "' . $to . '"
                 ' . $cond);
        while ($row = $this->db->assoc($inv_main_query)) {
            for ($i = 0; $i < count($excel_header); $i++) {
                $objPHPExcel->getActiveSheet()->SetCellValue($excel_header[$i] . $rowCount, $row[$header_arr[$i]]);
            }
            $rowCount++;
        }
        //        $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
        //        // Write the Excel file to filename some_excel_file.xlsx in the current directory
        //        //$objWriter->save('some_excel_file.xlsx'); 
        //        header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        //        header('Content-Disposition: attachment; filename="invoices.xlsx"');
        //        $objWriter->save('php://output');
        //               $detPHPExcel = new PHPExcel();
        $cond = ' ';
        if ($is_actual == 0) {
            $cond .= ' and i.is_actual = 0 ';
        }
        $objPHPExcel->createSheet(1);
        $objPHPExcel->setActiveSheetIndex(1);
        // Set the active Excel worksheet to sheet 0
        //        $objPHPExcel->setActiveSheetIndex(1);
        $rowCount = 1;
        $header_det_arr = ['ID', 'Invonum', 'ProductCode', 'Discount',
            'subtotal', 'PricePerUnit', 'Quantityperunit', 'Descripion',
            'ProfitPerItem', 'WHcode', 'WHcodeTo', 'Disc1',
            'Sale2', 'Line', 'Nm', 'Qout', 'Unit', 'CBar', 'CostA',
            'Cur2', 'EDateX', 'JobCode'];
        $excel_det_header = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'];
        for ($i = 0; $i < count($excel_det_header); $i++) {
            $objPHPExcel->getActiveSheet()->SetCellValue($excel_det_header[$i] . $rowCount, $header_det_arr[$i]);
        }
        $rowCount++;
        //check unit
        $inv_det_query = $this->db->query('select i.Invoice_ID_Auto,
            ""as ID,concat(i.invoice_prefix,i.Invoice_ID) as Invonum,p.Product_Code as ProductCode,(d.Product_Discount/100) as Discount,
            d.Product_Total_Price as subtotal,d.Product_Net_Price as PricePerUnit,d.Item_Quantity_Current as Quantityperunit,p.Product_Name as Descripion,
            d.unit_cost as ProfitPerItem,dep.Depot_Code as WHcode,0 as WHcodeTo,(d.Product_Net_Price *(1+(d.Product_Discount/100))) as Disc1,
            d.Product_Net_Price as Sale2,1 as Nm,d.Item_Quantity_Current as Qout,u.UOM_Name as Unit,"" as CBar,(d.Item_Quantity_Current*d.unit_cost) as CostA,
            cu.Currency_Symbol as Cur2,DATE_FORMAT(i.Invoice_Date, "%d-%b-%y") as EDateX,dep.Depot_Code as JobCode
                from tbl_invoice_products_details d join tbl_invoices i on  i.Invoice_ID_Auto = d.Invoice_ID_Auto
                join tbl_stock_products p on p.Product_ID = d.Product_ID
                join tbl_stock_depot_warehouse dep on dep.Depot_ID = i.Depot_ID
                join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency
                join tbl_stock_uom u on u.UOM_ID = d.UOM_ID
                where 
                i.Invoice_Date between "' . $from . '" and "' . $to . '"
                 ' . $cond);
        $j = 1;
        $inv_id = 0;
        while ($row = $this->db->assoc($inv_det_query)) {
            if ($row['Invoice_ID_Auto'] == $inv_id)
                $j++;
            else
                $j = 1;
            for ($i = 0; $i < count($excel_det_header); $i++) {
                $row['Line'] = $j;
                $objPHPExcel->getActiveSheet()->SetCellValue($excel_det_header[$i] . $rowCount, $row[$header_det_arr[$i]]);
            }
            $rowCount++;
            $inv_id = $row['Invoice_ID_Auto'];
        }
        $detWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
        // Write the Excel file to filename some_excel_file.xlsx in the current directory
        //$objWriter->save('some_excel_file.xlsx'); 
        header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment; filename="invoice_details.xlsx"');
        $detWriter->save('php://output');
        exit;
        //        exit;
    }

    public function export_invoice_details($from, $to, $is_actual) {
        //invoice_details
        $detPHPExcel = new PHPExcel();
        $cond = ' ';
        if ($is_actual == 0) {
            $cond .= ' and i.is_actual = 0 ';
        }
        // Set the active Excel worksheet to sheet 0
        $detPHPExcel->setActiveSheetIndex(0);
        $rowCount = 1;
        $header_det_arr = ['ID', 'Invonum', 'ProductCode', 'Discount',
            'subtotal', 'PricePerUnit', 'Quantityperunit', 'Descripion',
            'ProfitPerItem', 'WHcode', 'WHcodeTo', 'Disc1',
            'Sale2', 'Line', 'Nm', 'Qout', 'Unit', 'CBar', 'CostA',
            'Cur2', 'EDateX', 'JobCode'];
        //Yousif I add this
        $excel_header = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
        $excel_det_header = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V'];
        for ($i = 0; $i < count($excel_header); $i++) {
            $detPHPExcel->getActiveSheet()->SetCellValue($excel_det_header[$i] . $rowCount, $header_det_arr[$i]);
        }
        $rowCount++;
        //check unit
        $inv_det_query = $this->db->query('select 
            ""as ID,concat(i.invoice_prefix,i.Invoice_ID) as Invonum,p.Product_Code as ProductCode,(d.Product_Discount/100) as Discount,
            d.Product_Total_Price as subtotal,d.Product_Net_Price as PricePerUnit,d.Item_Quantity_Current as Quantityperunit,p.Product_Name as Descripion,
            d.unit_cost as ProfitPerItem,dep.Depot_Code as WHcode,0 as WHcodeTo,(d.Product_Net_Price *(1+(d.Product_Discount/100))) as Disc1,
            d.Product_Net_Price as Sale2,1 as Nm,d.Item_Quantity_Current as Qout,u.UOM_Name as Unit,"" as CBar,(d.Item_Quantity_Current*d.unit_cost) as CostA,
            cu.Currency_Symbol as Cur2,DATE_FORMAT(i.Invoice_Date, "%d-%b-%y") as InvoiceDate,dep.Depot_Code as JobCode
                from tbl_invoice_products_details d join tbl_invoices i on  i.Invoice_ID_Auto = d.Invoice_ID_Auto
                join tbl_stock_products p on p.Product_ID = d.Product_ID
                join tbl_stock_depot_warehouse dep on dep.Depot_ID = i.Depot_ID
                join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency
                join tbl_stock_uom u on u.UOM_ID = d.UOM_ID
                where 
                i.Invoice_Date between "' . $from . '" and "' . $to . '"
                 ' . $cond);
        while ($row = $this->db->assoc($inv_det_query)) {
            for ($i = 0; $i < count($excel_det_header); $i++) {
                $detPHPExcel->getActiveSheet()->SetCellValue($excel_det_header[$i] . $rowCount, $row[$header_det_arr[$i]]);
            }
            $rowCount++;
        }
        $detWriter = new PHPExcel_Writer_Excel2007($detPHPExcel);
        // Write the Excel file to filename some_excel_file.xlsx in the current directory
        //$objWriter->save('some_excel_file.xlsx'); 
        header('Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment; filename="invoice_details.xlsx"');
        $detWriter->save('php://output');
        exit;
    }

    function getSalesOrderByID($SID) {
        $data = array();
        $query = $this->db->prepare_Stmt('select * from sales_order_list where Sales_Order_ID = ?', [&$SID]);
        $row = $this->db->assoc($query);
        $data['Main'] = $row;
        $quer_dtls = $this->db->prepare_Stmt('select s.*,GROUP_CONCAT(uom_from separator "/") AS Product_UOM from sales_order_detailes s left join tbl_uom_conversions u on (s.Product_ID = u.Product_ID) where Order_ID = ? group by u.Product_ID', [&$SID]);
        while ($row_dtl = $this->db->assoc($quer_dtls)) {
            $data['details'][] = $row_dtl;
        }
        return $data;
    }

    //    public function editSalesOrder() {
    //
    //        $is_invoice = 1;
    //        if (!$this->stop_transaction_start_end)
    //            $this->db->query('START TRANSACTION;');
    //        $order = [&$this->info['Vendor_ID'], &$this->info['Order_Date'], &$this->info[0],&$this->info['Order_ID']];
    //        $this->db->prepare_Stmt(" Update  tbl_garage_sales_order set Customer_ID = ? ,Sales_Order_Date = ? ,Logged_ID = ? where Sales_Order_ID = ?", $order);
    //        $this->db->prepare_Stmt("Delete from  tbl_garage_sales_order_details  where Sales_Order_ID = ? ", [&$this->info['Order_ID']]);
    //
    //
    //        if (is_array($this->info['Items'])) {
    //            foreach ($this->info['Items'] as $item) {
    //                $product_quantity = Product::getConvertedQuantity($item['UOM_ID'], $item['Quantity'], $item['Item_ID']);
    //                $details = [&$this->info['Order_ID'], &$item['Item_ID'], &$product_quantity, &$item['Quantity'], &$item['UOM_ID'], &$item['Unit_Price'], &$this->info['Currency_ID']];
    //                $this->db->prepare_Stmt("INSERT INTO tbl_garage_sales_order_details (Sales_Order_ID,Product_ID,Quantity,Item_Quantity_Current,UOM_ID,Unit_Price,Currency_ID) VALUES (?,?,?,?,?,?,?) ", $details);
    //            }
    //        }
    //        $error = $this->db->error();
    //        if (empty($error)) {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query("COMMIT");
    //        } else {
    //            if (!$this->stop_transaction_start_end)
    //                $this->db->query("ROLLBACK");
    //        }
    //        return array_unique($error);
    //    }
    // fast solution to solve the pos print problem with can not print phone, address pos customer
    public function get_cus_pos($id) {
        $query_main = $this->db->query(' SELECT * FROM tbl_pos_customers
        where customer_id = "' . smc_escape($id) . '"');
        $row = $this->db->assoc($query_main);
        return $row;
    }
    public function getInvoiceToPrint($id, $fire_level = null) {
        $products_without_vat = smc_session()['default_setting']['products_without_vat'] == '1' ? 1:0;
        $data = array('main' => array(), 'Details' => array(), 'DetailsLinked' => array());
        $printers_id = array();
        $query_main = $this->db->query('select *,(Invoice_VAT*current_rate) as local_vat_amount,
                    (vat1_total*current_rate) as local_vat1_amount,(vat2_total*current_rate) as local_vat2_amount,cb.customer_branch_name
                from invoice_list_main p
                    left join tbl_customer_branches cb on (cb.customer_branch_id = p.customer_branch_id)
                where Invoice_ID_Auto = "' . smc_escape($id) . '"
                and current_year_id = "' . $this->year_id . '"');
        $row = $this->db->assoc($query_main);
        if (empty($row))
            return array();
        //in case we need to add specific variable we use custom path
        if (method_exists($this, 'parseInvoiceToPrintRow'))
            $this->parseInvoiceToPrintRow($row);
        //
        $product_total_price_without_vat = 0;
        $product_total_price_with_vat = 0;
        $product_total_price_ttc_with_vat = 0;

        $product_total_price_without_vat_before_disc = 0;
        $product_total_price_with_vat_before_disc = 0;

        $all_product_total_price_before_disc = 0;

        $product_total_price_ttc_with_vat_before_disc = 0;

        $product_total_price_with_vat_pos = 0;
        $product_total_price_ttc_with_vat_before_disc_pos = 0;
        $product_total_price_ttc_with_vat_pos = 0;

        $total_vat_amount_before_disc = 0;

        

        $row['driver_name'] = CommonBusiness::getDriverByDriverId($row['driver_id']);

        if(isset($row['sales_order_id']) && $row['sales_order_id'] != 0 ){
            $sales_order_id = $row['sales_order_id'];
            $query_main_order = $this->db->query('select * from tbl_purchase_order  where Order_ID = ' . $sales_order_id . '');
            $row_order = $this->db->assoc($query_main_order);
            if(isset($row_order['Order_ID_Auto']))
                $row['sales_order_id'] = $row_order['sale_prefix'].' '.$row_order['Order_ID_Auto'];
            
        }
        else{
            $row['hide_sales_order_id'] = 'hidden';
            
        }


        $row['track_code'] = CommonFunctions::generate_track_code($id, 'inv');
        $row['branch_name'] = CommonBusiness::getBranchNameByDepot($row['Depot_ID'])['branch_name'];
        $row['tbl_als_name'] = empty($row['table_alias_name']) ? $row['table_name'] : $row['table_alias_name'];
        $row['Invoice_Date_format'] = !empty(smc_session()['default_setting']['report_format_date']) ? date(smc_session()['default_setting']['report_format_date'], strtotime($row['Invoice_Date'])) : $row['Invoice_Date'];
        $row['Invoice_Due_Date_format'] = !empty(smc_session()['default_setting']['report_format_date']) ? date(smc_session()['default_setting']['report_format_date'], strtotime($row['Invoice_Due_Date'])) : $row['Invoice_Due_Date'];
        $row['postponed_date_time'] = empty($row['postponed_date_time']) ? '' : date('Y-m-d H:i', strtotime($row['postponed_date_time']));
        $net_total = $row['Invoice_Net_Total'];
        $shipping_amount = $row['Invoice_Shipping'];
        $paid_amount = $row['Invoice_Paid_Amount'];


        $invoice_first_cash  = $row['first_cash_Invoice_Paid_Amount'];
        $invoice_first_symbol = CurrencyFactory::getCurrencySymbol($row['Invoice_Currency']);


        $invoice_second_cash  = $row['second_cash_Invoice_Paid_Amount'];
        $invoice_second_rate  = $row['second_cash_currency_rate'];
        $invoice_second_symbol  = CurrencyFactory::getCurrencySymbol($row['second_cash_Invoice_Currency']);

        $total_first_cash =  ($invoice_second_cash * $invoice_second_rate) + $invoice_first_cash ;
        if($row['Invoice_Currency'] == smc_session()['local_currency']){
            $total_second_cash =  ($invoice_first_cash *  $row['second_currency_rate'] ) + $invoice_second_cash ;
        }else{
            $total_second_cash =  ($invoice_first_cash * $row['current_rate']) + $invoice_second_cash ;
        }

        $row['invoice_first_cash'] = CommonFunctions::public_round_number($invoice_first_cash).' '.$invoice_first_symbol;
        $row['invoice_second_cash'] = CommonFunctions::public_round_number($invoice_second_cash).' '.$invoice_second_symbol;
        
        $row['total_first_cash'] =  CommonFunctions::public_round_number($total_first_cash).' '.$invoice_first_symbol;
        $row['total_second_cash'] =  CommonFunctions::public_round_number($total_second_cash).' '.$invoice_second_symbol;

        $row['invoice_first_symbol'] =  $invoice_first_symbol;
        $row['invoice_second_symbol'] =  $invoice_second_symbol;

        // $prec = 2;  //$row['Currency_ID'] == 84 ? 0 : 2;    since if zero it will make round
        $local_vat_amount = $row['local_vat_amount'];
        $local_vat1_amount = $row['local_vat1_amount'];
        $local_vat2_amount = $row['local_vat2_amount'];
        $cash_amount = $row['cash_amount'];
        $unpaid_amount = $net_total + $shipping_amount - $paid_amount;
        $grand_total = $net_total + $shipping_amount + $row['inv_currency_round'];
        $inv_disc_amount = $row['discount_amount'];
        $inv_disc_percentage = $row['Invoice_Discount'];
        $row['invoice_net_total_before_vat'] = $row['Invoice_Sub_Total'] - $inv_disc_amount;
        $row['cash_amount'] = CommonFunctions::formatNumber($cash_amount);
        $row['cash_class'] = $cash_amount > 0 ? '' : 'hidden';
        $row['unpaid_amount'] = CommonFunctions::public_round_number($unpaid_amount);
        $row['Invoice_Sub_Total'] = CommonFunctions::formatNumber($row['Invoice_Sub_Total']);
        $row['Invoice_Net_Total'] = CommonFunctions::formatNumber($row['Invoice_Net_Total']);
        $row['Invoice_Paid_Amount'] = CommonFunctions::formatNumber($row['Invoice_Paid_Amount']);
        $row['Invoice_VAT'] = CommonFunctions::formatNumber($row['Invoice_VAT']);
        $row['Invoice_Discount'] = CommonFunctions::formatNumber($inv_disc_percentage);
        $row['discount_amount'] = CommonFunctions::formatNumber($inv_disc_amount);
        $row['Invoice_Shipping'] = CommonFunctions::formatNumber($row['Invoice_Shipping']);
        $row['local_vat_amount'] = CommonFunctions::formatNumber($local_vat_amount);
        $row['local_vat1_amount'] = CommonFunctions::formatNumber($local_vat1_amount);
        $row['local_vat2_amount'] = CommonFunctions::formatNumber($local_vat2_amount);
        $row['local_net_total'] = CommonFunctions::formatNumber(($net_total * $row['current_rate']));
        $row['order_time'] = $row['Is_Delivery'] == 0 ? $row['date_time'] : $row['Delivery_Time'];
        $row['net_total_in_usd'] = CommonFunctions::formatNumber(CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['Currency_ID'], 144, $net_total));
        $row['net_total_in_lb'] = CommonFunctions::formatNumber(CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['Currency_ID'], 84, $net_total));
        $row['grand_total'] = CommonFunctions::formatNumber($grand_total);
        $row['grand_total_no_format'] = $grand_total;
        $row['table_class'] = empty($row['table_name']) ? 'hidden' : '';
        $row['persons_count_class'] = $row['Persons_Count'] != 0 ? '' : 'hidden';
        $row['customer_data_hide'] = (empty($row['Customer_ID']) && empty($row['pos_customer_id'])) ? 'hidden' : '';
        $row['grand_total_word_ar'] = Forms::num_to_word($grand_total, $row['Currency_ID'], 'ar');
        $row['grand_total_word_en'] = Forms::num_to_word($grand_total, $row['Currency_ID'], 'en');
        $row['grand_total_word_second_ar'] = Forms::num_to_word($row['net_total_in_lb'], smc_session()['default_setting']['second_currency'], 'ar');
        $row['total_vat_word_ar'] = Forms::num_to_word($row['Invoice_VAT'], $row['Currency_ID'], 'ar');
        $row['total_vat_word_en'] = Forms::num_to_word($row['Invoice_VAT'], $row['Currency_ID'], 'en');
        $row['total_vat1_word_ar'] = Forms::num_to_word($row['vat1_total'], $row['Currency_ID'], 'ar');
        $row['total_vat1_word_en'] = Forms::num_to_word($row['vat1_total'], $row['Currency_ID'], 'en');
        $row['total_vat2_word_ar'] = Forms::num_to_word($row['vat2_total'], $row['Currency_ID'], 'ar');
        $row['total_vat2_word_en'] = Forms::num_to_word($row['vat2_total'], $row['Currency_ID'], 'en');
        $row['local_vat_word_ar'] = Forms::num_to_word($local_vat_amount, smc_session()['local_currency'], 'ar');
        $row['local_vat_word_en'] = Forms::num_to_word($local_vat_amount, smc_session()['local_currency'], 'en');
        $row['local_vat1_word_ar'] = Forms::num_to_word($local_vat1_amount, smc_session()['local_currency'], 'ar');
        $row['local_vat1_word_en'] = Forms::num_to_word($local_vat1_amount, smc_session()['local_currency'], 'en');
        $row['local_vat2_word_ar'] = Forms::num_to_word($local_vat2_amount, smc_session()['local_currency'], 'ar');
        $row['local_vat2_word_en'] = Forms::num_to_word($local_vat2_amount, smc_session()['local_currency'], 'en');
        $row['invoice_net_total_before_vat'] = CommonFunctions::formatNumber($row['invoice_net_total_before_vat']);

        $exchange_rate_first_sec_arr = CurrencyFactory::returnExchangeRate(smc_session()['local_currency'],smc_session()['second_currency']['id']);
        $exchange_rate_first_sec = $exchange_rate_first_sec_arr[1] == '*' ? $exchange_rate_first_sec_arr[0] : (1 / $exchange_rate_first_sec_arr[0]);

        $exchange_rate_sec_first_arr = CurrencyFactory::returnExchangeRate(smc_session()['second_currency']['id'],smc_session()['local_currency']);
        $exchange_rate_sec_first = $exchange_rate_sec_first_arr[1] == '*' ? $exchange_rate_sec_first_arr[0] : (1 / $exchange_rate_sec_first_arr[0]);
        $local_currency_rate = $exchange_rate_first_sec;
        $second_currency_rate = $exchange_rate_sec_first;
        $invoice_Currency_Code = $row['Currency_Code'] ;


        //$row['printed_before_class'] = isset($this->info['printed_before']) ? '' : 'hidden';
        $row['delivery_class'] = $row['invoice_type'] == 2 ? '' : 'hidden';
        $row['takeaway_class'] = $row['invoice_type'] == 6 ? '' : 'hidden';
        $row['note_class'] = !empty($row['Invoice_Description']) ? '' : 'hidden';
        $row['order_note_class'] = !empty($row['order_note']) ? '' : 'hidden';
        $row['edit_url'] = 'Inventory/addpurchase/sales/' . ($row['is_actual'] == 1 ? 'act/' : '') . $id;
        //
        if ($row['Customer_ID'] == 0)
            $row['current_balance'] = $row['previous_balance'] = '---';
        else {
            $report = new Report;
            //we used 2000-01-01 00:00:00 as from date for the case that transaction is entered in date of next current year with date created this year
            $temp_current_balance = $report->returnCustomerExactBalance($row["Customer_ID"], $row["Currency_ID"], '2000-01-01 00:00:00', $row["date_created"]/* date('Y-m-d') */, 0, $row['is_actual']);
            $row['current_balance'] = CommonFunctions::formatNumber($temp_current_balance['Balance']);
            $row['previous_balance'] = CommonFunctions::formatNumber(($temp_current_balance['Balance'] - ($net_total - $paid_amount)));
        }
        //
        $row['shipp'] = CommonLanguage::getMessage('take_away');
        if ($row['invoice_type'] == 2) {
            $row['shipp'] = CommonLanguage::getMessage('delivery');
        } elseif ($row['invoice_type'] == 6) {
            $row['shipp'] = CommonLanguage::getMessage('pre_take_away');
        } elseif (!empty($row['table_id'])) {
            $row['shipp'] = CommonLanguage::getMessage('table');
        }
        $row['payment_type'] = '';
        if ($row['Invoice_Status'] == 0) {
            $row['payment_type'] = CommonLanguage::getMessage('unpaid');
        } elseif ($row['Invoice_Status'] == 1) {
            $row['payment_type'] = CommonLanguage::getMessage('partially_paid');
        } elseif ($row['Invoice_Status'] == 2) {
            $row['payment_type'] = CommonLanguage::getMessage('paid');
        }
        //        else if (($net_total + $shipping_amount) <= $paid_amount) {
        //            $row['shipp'] = CommonLanguage::getMessage('cash');
        //        } else {
        //            $row['shipp'] = CommonLanguage::getMessage('on_credit');
        //        }
        if (!empty($row['pos_customer_id'])) {
            $person = Customer::getPOSCustomerByID($row['pos_customer_id'], $row['address_id']);
        } else {
            $person = Customer::getCustomerByID($row['Customer_ID']);
        }
        $person['Address'] = !empty($row['customer_address_alias']) ? $row['customer_address_alias'] : $person['Address'];
        $person['Name'] = !empty($row['customer_name_alias']) ? $row['customer_name_alias'] : $person['Name'];
        $person['customer_address'] = $person['Address'];
        $person['customer_phone'] = $person['Phone'];
        $person['customer_email'] = $person['Email'];
        $data['main'] = array_merge($row, $person);
        $fire_cond = '';
        if (!empty($fire_level))
            $fire_cond = ' and i.hold = "' . $fire_level . '" and i.is_fired=0 ';
        
        $query_Product_Total_Price_TTC =    $products_without_vat == 1 ? 'i.Product_Total_Price AS Product_Total_Price_TTC,' :  '(i.Product_Total_Price+i.vat_amount+i.vat2_amount) as Product_Total_Price_TTC,';
        $query_details = $this->db->query($x ='select
                                                p.Invoice_ID_Auto AS Invoice_ID_Auto,
                                                i.from_time,
                                                i.to_time,
                                                i.modify_date,
                                                i.driver_id,
                                                drv.driver_name,
                                                i.Entery_ID,
                                                i.Item_Quantity_Current,
                                                ps.Product_Code AS Code,
                                                ps.Category_ID AS Category_ID,
                                                cat.Cat_Name AS Cat_Name,
                                                ps.product_second_code AS second_code,
                                                ps.Product_Name AS Product_Name,
                                                ps.Product_Name AS Name,
                                                ps.Printer_ID,
												ps.Product_Arabic_Name,
                                                ps.Product_Limit_Discount,
                                                i.Product_ID AS Product_ID,
                                                i.vat_percent,
                                                i.vat_amount,i.vat2_percent,i.vat2_amount,
                                                i.unit_cost,
                                                if(i.expiry_date = "0000-00-00","",i.expiry_date) as expiry_date,
                                                i.product_description,
                                                uc.Bar_Code,
                                                '.
                                                $query_Product_Total_Price_TTC
                                                .'
                                                i.Product_Discount AS Product_Discount,
                                                i.Discount_Amount, i.Product_Quantity,
                                                i.Product_Net_Price AS Product_Net_Price,
                                                i.Product_Total_Price AS Product_Total_Price,
                                                 i.UOM_ID,u.UOM_Name,ps.brand_id,b.brand_name,i.lot_nb,i.serial_nb,
                                                 group_concat(crit_detail.criteria_detail_name SEPARATOR "#$#") as TAG,
                                                 i.date_created as details_date_created,i.hold
										from tbl_invoice_products_details i 
                                            inner join tbl_invoices p on p.Invoice_ID_Auto = i.Invoice_ID_Auto
                                            inner JOIN uom_conversions uc ON uc.Product_ID = i.Product_ID and uc.uom_from = i.UOM_ID
                                            inner join tbl_stock_products ps on ps.Product_ID = i.Product_ID
                                            inner join tbl_stock_uom u on u.UOM_ID = i.UOM_ID
                                            inner join tbl_product_cat cat on cat.Cat_ID = ps.Category_ID
                                            left join tbl_drivers drv on drv.driver_id = i.driver_id
                                            left join tbl_brand_products b on b.brand_id = ps.brand_id
                                            left join tbl_invoice_product_criteria criteria on criteria.Entery_ID = i.Entery_ID 
                                            left join tbl_product_criteria_detail crit_detail on crit_detail.criteria_detail_id=criteria.criteria_detail_id
                                            where p.current_year_id = "' . $this->year_id . '"
                                            and p.Invoice_ID_Auto = "' . $id . '" ' . $fire_cond . '
                                        group by  i.`Entery_ID` ');
        $i = 0;
        $tmp_items_arr = array();
        $item_ids_arr = array();
        $entry_ids_arr = array();
        while ($row = $this->db->assoc($query_details)) {
            $tag = $row['TAG'];
            $row['TAG'] = str_replace('#$#', ' , ', $tag);
            $row['tag_lines'] = str_replace('#$#', '<br/>', $tag);
            $tmp_items_arr[$row['Entery_ID']] = $row;
            $entry_ids_arr[] = $row['Entery_ID'];
            $tmp_items_arr[$row['Entery_ID']]['add_ons'] = '';
            $item_ids_arr[$row['Product_ID']] = $row['Product_ID'];
        }
        //
        $print_uom_arr = array();
        $query = $this->db->query('select p.print_uom_id,p.Product_ID,u.conversion_amount from tbl_stock_products p
            join tbl_uom_conversions u on u.Product_ID = p.Product_ID and p.print_uom_id = u.uom_from
            where p.Product_ID in (' . implode(',', $item_ids_arr) . ')');
        while ($row = $this->db->assoc($query)) {
            $print_uom_arr[$row['Product_ID']] = $row;
        }
        //
        if (!empty($entry_ids_arr)) {
            $add_ons_details_query = $this->db->query('select 
                            prod_add_ons.Entery_ID,add_ons.add_ons_details_id,
                            group_concat(concat(add_ons.add_ons_details_title,"---",prod_add_ons.Quantity) SEPARATOR ",") as details
                                                   from  tbl_invoice_product_add_ons prod_add_ons
                                                   inner join tbl_add_ons_details add_ons
                                                   using(add_ons_details_id)
                                                   where prod_add_ons.Entery_ID IN (' . implode(',', $entry_ids_arr) . ')
                                                   group by prod_add_ons.Entery_ID
        ');
            while ($row_add_ons = $this->db->assoc($add_ons_details_query)) {
                $tmp_items_arr[$row_add_ons['Entery_ID']]['add_ons'] = $row_add_ons['details'];
            }
            $tmp_items_arr = array_values($tmp_items_arr);
            $item_link_arr = array();
            $link_query = $this->db->query('select k.*,p.Product_Name,p.Product_Name AS Name,p.Product_Arabic_Name,p.Printer_ID,  p.Product_Code AS Code, 
			p.product_second_code AS second_code, p.Product_Limit_Discount, p.Product_ID,u.UOM_Name
				from tbl_products_link k join tbl_stock_products p on p.Product_ID = k.sub_product_id
					join tbl_stock_uom u on u.UOM_ID = k.UOM_ID
            where main_product_id in (' . implode(',', $item_ids_arr) . ') and operation="-"');
            $count_row = $this->db->rowsno($link_query);
            if ($count_row > 0) {
                while ($row_link = $this->db->assoc($link_query)) {
                    $item_link_arr[$row_link['main_product_id']][] = $row_link;
                }
            }
            $link_query = $this->db->query('select k.option_quantity as current_quantity,
				k.UOM_ID,d.Product_ID as main_product_id,u.UOM_Name,k.product_id as sub_product_id,
				p.Product_Name,p.Product_Name AS Name,p.Product_Arabic_Name,p.Printer_ID,  p.Product_Code AS Code, p.product_second_code AS second_code,
				p.Product_Limit_Discount, p.Product_ID
			from tbl_invoice_product_options k 
                join tbl_invoice_products_details d on d.Entery_ID = k.invoice_detail_id
                join tbl_stock_products p on p.Product_ID = k.product_id
                join tbl_stock_uom u on u.UOM_ID = k.UOM_ID
            where Invoice_ID_Auto = "' . $id . '"');
            $count_row = $this->db->rowsno($link_query);
            if ($count_row > 0) {
                while ($row_link = $this->db->assoc($link_query)) {
                    $item_link_arr[$row_link['main_product_id']][] = $row_link;
                }
            }
            //
            $flds_link_empty = array('Product_Net_Price', 'Product_Net_Price_TTC', 'Product_Net_Price_After_Disc', 'Product_Net_Price_After_Disc_TTC', 'Product_Total_Price_After_Disc'
                , 'Product_Total_Price_After_Disc_TTC', 'Product_Total_Price_Before_Disc', 'Product_Total_Price_TTC_Before_Disc', 'Discount_Amount', 'Product_Discount', 'Product_Total_Price'
                , 'Product_Total_Price_TTC', 'vat_amount', 'vat2_amount', 'total_with_vat', 'hold_class', 'Bar_Code', 'vat_percent', 'vat2_percent', 'expiry_date', 'lot_nb', 'serial_nb');
            //
            $data['main']['invoice_total_quantity'] = 0;
            $inv_ttl_row_disc = 0;    //total discount for all rows
            $inv_sub_ttl_ttc = 0;   //total ttc before invoice discount
            $old_hold = 0;
            $old_hold_prntr = array();
            $data['disc_items'] = $data['no_disc_items'] = $data['disc_items_linked'] = $data['no_disc_items_linked'] = array();
            foreach ($tmp_items_arr as $item_row) {
                $data['main']['invoice_total_quantity'] += $item_row['Item_Quantity_Current'];
                $inv_ttl_row_disc += $item_row['Discount_Amount'];
                //
                $item_row['uom_conv_qty'] = !empty($print_uom_arr[$item_row['Product_ID']]) ? ($item_row['Product_Quantity'] / $print_uom_arr[$item_row['Product_ID']]['conversion_amount']) : 0;
                $item_row['uom_conv_amt'] = !empty($print_uom_arr[$item_row['Product_ID']]) ? $print_uom_arr[$item_row['Product_ID']]['conversion_amount'] : 0;
                //
                $total_price = $item_row['Product_Total_Price'];
                $vat_amount = $item_row['vat_amount'];
                $vat2_amount = $item_row['vat2_amount'];
                
                //
                $item_row['Product_Net_Price_TTC'] = $item_row['Product_Net_Price'] * (1 + ($item_row['vat_percent'] / 100));
                $item_row['Product_Net_Price_TTC'] = $item_row['Product_Net_Price_TTC'] * (1 + ($item_row['vat2_percent'] / 100));
                //
                $item_row['Product_Net_Price_After_Disc'] = $item_row['Product_Net_Price'] * (1 - ($item_row['Product_Discount'] / 100));
                $item_row['Product_Net_Price_After_Disc_TTC'] = $item_row['Product_Net_Price_After_Disc'] * (1 + ($item_row['vat_percent'] / 100));
                $item_row['Product_Net_Price_After_Disc_TTC'] = $item_row['Product_Net_Price_After_Disc_TTC'] * (1 + ($item_row['vat2_percent'] / 100));
                //
                $item_row['Product_Total_Price_taxable_amount'] =  $item_row['vat_amount'] > 0 ? $item_row['Product_Total_Price']: 0;

                $item_row['Product_Total_Price_TTC_Before_Disc'] = $item_row['Product_Net_Price_TTC'] * $item_row['Item_Quantity_Current'];
                $item_row['Product_Total_Price_Before_Disc'] = $item_row['Product_Net_Price'] * $item_row['Item_Quantity_Current'];
                $item_row['Product_Total_Price_After_Disc'] = $item_row['Product_Net_Price_After_Disc'] * $item_row['Item_Quantity_Current'];
                $item_row['Product_Total_Price_After_Disc_TTC'] = $item_row['Product_Net_Price_After_Disc_TTC'] * $item_row['Item_Quantity_Current'];
                $inv_sub_ttl_ttc += $item_row['Product_Total_Price_After_Disc_TTC'];
                //Invoice_Discount Product_Discount
                $total_product_no_vat_no_disc = $item_row['Product_Net_Price']*$item_row['Product_Quantity'];
                $vat_amount_before_disc = ($total_product_no_vat_no_disc * $item_row['vat_percent'])/100;
                $total_vat_amount_before_disc += ($total_product_no_vat_no_disc * $item_row['vat_percent'])/100;

                if($vat_amount > 0 || $vat2_amount > 0 ){
                    $product_total_price_with_vat +=  $total_price;
                    $product_total_price_ttc_with_vat = $product_total_price_ttc_with_vat + ($total_price + $vat_amount + $vat2_amount);
                
                }
                else {
                    $product_total_price_without_vat +=  $total_price;
                    
                }

                if($vat_amount > 0 || $vat2_amount > 0 ){
                    $product_total_price_with_vat_before_disc +=  $item_row['Product_Total_Price_Before_Disc'];
                    $product_total_price_ttc_with_vat_before_disc = $product_total_price_ttc_with_vat_before_disc + ($item_row['Product_Total_Price_Before_Disc'] + $vat_amount_before_disc + $vat2_amount);
                
                }
                else {
                    $product_total_price_without_vat_before_disc +=  $item_row['Product_Total_Price_Before_Disc'];
                }

                if($vat_amount > 0 || $vat2_amount > 0 ){

                    $disc_amount_product = $total_product_no_vat_no_disc - (($total_product_no_vat_no_disc * $item_row['Product_Discount']) / 100);
                    $disc_amount_product = $disc_amount_product - (($disc_amount_product *  $inv_disc_percentage ) / 100);
                    
                    $product_total_price_with_vat_pos +=  $disc_amount_product;
                    $product_total_price_ttc_with_vat_before_disc_pos = $product_total_price_ttc_with_vat_before_disc_pos + ($total_product_no_vat_no_disc + $vat_amount_before_disc + $vat2_amount);
                    $product_total_price_ttc_with_vat_pos =  $product_total_price_ttc_with_vat_pos + ($total_price + $vat_amount + $vat2_amount);
                
                }
                else {
                    $total_product_no_vat_no_disc = $total_product_no_vat_no_disc - (($total_product_no_vat_no_disc * $item_row['Product_Discount'])/100);
                }

                if($invoice_Currency_Code != smc_session()['local_currency_code']){
                    $item_row['Product_Net_Price_TTC_second'] = CommonFunctions::formatNumber($item_row['Product_Net_Price_TTC'] /  $local_currency_rate).' ' .smc_session()['default_currency']['Currency_Symbol']; 
                }else{
                    $item_row['Product_Net_Price_TTC_second'] = CommonFunctions::formatNumber($item_row['Product_Net_Price_TTC'] * $local_currency_rate).' '.smc_session()['second_currency']['symbol']; 
                }
                if($invoice_Currency_Code != smc_session()['local_currency_code']){
                    $item_row['Product_Total_Price_After_Disc_TTC_second'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_After_Disc_TTC'] /  $local_currency_rate).' ' .smc_session()['default_currency']['Currency_Symbol']; 
                }else{
                    $item_row['Product_Total_Price_After_Disc_TTC_second'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_After_Disc_TTC'] * $local_currency_rate).' '.smc_session()['second_currency']['symbol']; 
                }

                $item_row['Product_Net_Price'] = CommonFunctions::formatNumber($item_row['Product_Net_Price']);  //unit price without vat and before disc.
                $item_row['Product_Net_Price_TTC'] = CommonFunctions::formatNumber($item_row['Product_Net_Price_TTC']);  //ttc unit price with vat and before disc.
                $item_row['Product_Net_Price_After_Disc'] = CommonFunctions::formatNumber($item_row['Product_Net_Price_After_Disc']);  //unit price after product disc. & before no inv. disc
                $item_row['Product_Net_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($item_row['Product_Net_Price_After_Disc_TTC']);  //ttc unit price with vat and after product disc. & before inv. disc
                $item_row['Product_Total_Price_After_Disc'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_After_Disc']);  //total price after product disc. & before no inv. disc
                $item_row['Product_Total_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_After_Disc_TTC']);  //ttc total price with vat and after product disc. & before inv. disc
                $item_row['Product_Total_Price_Before_Disc'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_Before_Disc']);  //total price before product disc. & before no inv. disc without vat
                $item_row['Product_Total_Price_TTC_Before_Disc'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_TTC_Before_Disc']);  //total price before product disc. & before no inv. disc with vat
                $item_row['Discount_Amount'] = CommonFunctions::formatNumber($item_row['Discount_Amount']);
                $item_row['Product_Discount'] = CommonFunctions::formatNumber($item_row['Product_Discount']);
                $item_row['Product_Total_Price'] = CommonFunctions::formatNumber($item_row['Product_Total_Price']);  //total price after invoice & product discount
                $item_row['Product_Total_Price_TTC'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_TTC']);  //ttc total price after invoice & product discount with vat
                $item_row['vat_amount'] = CommonFunctions::formatNumber($item_row['vat_amount']);
                $item_row['vat2_amount'] = CommonFunctions::formatNumber($item_row['vat2_amount']);
                $item_row['Item_Quantity'] = $item_row['Item_Quantity_Current'];
                $item_row['Product_Quantity'] = CommonFunctions::formatNumber($item_row['Product_Quantity']);
                $item_row['Item_Quantity_Current'] = CommonFunctions::formatNumber($item_row['Item_Quantity_Current']);
                $item_row['Count'] = ++$i;
                $item_row['link_product_class'] = 'hidden';
                $item_row['total_with_vat'] =  CommonFunctions::formatNumber(($total_price + $vat_amount + $vat2_amount));
                $item_row['hold_class'] = $item_row['hold'] != $old_hold ? '' : 'hidden';
                $item_row['hold_text'] = $item_row['hold'];
                $item_row['fire_class'] = !empty($fire_level) ? '' : 'hidden';
                $item_row['fire_opposite_class'] = empty($fire_level) ? '' : 'hidden';
                $old_hold = $item_row['hold'];
                $data['Details'][] = $item_row;
                $data['DetailsLinked'][] = $item_row;
                if (smc_session()['default_setting']['inv_disc_items_arr_seperately'] == 1) {
                    if ($item_row['Product_Discount'] > 0) {
                        $data['disc_items'][] = $item_row;
                        $data['disc_items_linked'][] = $item_row;
                    } else {
                        $data['no_disc_items'][] = $item_row;
                        $data['no_disc_items_linked'][] = $item_row;
                    }
                }
                //
                if (!empty($item_row['Printer_ID'])) {
                    $printer_array = explode(",", $item_row['Printer_ID']);
                    foreach ($printer_array as $printer_id) {
                        if (!isset($old_hold_prntr[$printer_id]))
                            $old_hold_prntr[$printer_id] = 0;
                        $item_row['hold_class'] = $item_row['hold'] != $old_hold_prntr[$printer_id] ? '' : 'hidden';
                        $old_hold_prntr[$printer_id] = $item_row['hold'];
                        //
                        $data['printers'][$printer_id][] = $item_row;
                        if (empty($item_link_arr[$item_row['Product_ID']]))
                            $data['printers_linked'][$printer_id][] = $item_row;
                        if (!in_array($printer_id, $printers_id)) {
                            $printers_id[] = $printer_id;
                        }
                    }
                }
                //
                if (!empty($item_link_arr[$item_row['Product_ID']])) {
                    foreach ($item_link_arr[$item_row['Product_ID']] as $row_link) {
                        $row_link['Item_Quantity_Current'] = CommonFunctions::formatNumber($item_row['Item_Quantity_Current'] * $row_link['current_quantity']);
                        $row_link['Product_ID'] = $row_link['sub_product_id'];
                        $row_link['Name'] = $row_link['Product_Name'];
                        $row_link['Product_Arabic_Name'] = $row_link['Product_Arabic_Name'];
                        $row_link['details_date_created'] = $item_row['details_date_created'];
                        //
                        $row_link['link_product_class'] = '';
                        $row_link['product_description'] = '';
                        $row_link['TAG'] = '';
                        $row_link['tag_lines'] = '';
                        $row_link['add_ons'] = '';
                        $row_link['hold_class'] = 'hidden';
                        $row_link['hold_text'] = '';
                        $row_link['fire_class'] = 'hidden';
                        $row_link['fire_opposite_class'] = '';
                        $row_link['Count'] = '';
                        //
                        foreach ($flds_link_empty as $fld_name)
                            $row_link[$fld_name] = '--';
                        //
                        $data['DetailsLinked'][] = $row_link;
                        if (smc_session()['default_setting']['inv_disc_items_arr_seperately'] == 1) {
                            if ($item_row['Product_Discount'] > 0) {
                                $data['disc_items'][] = $row_link;
                                $data['disc_items_linked'][] = $row_link;
                            } else {
                                $data['no_disc_items'][] = $row_link;
                                $data['no_disc_items_linked'][] = $row_link;
                            }
                        }
                        if (!empty($row_link['Printer_ID'])) {
                            $printer_array = explode(",", $row_link['Printer_ID']);
                            foreach ($printer_array as $printer_id) {
                                $data['printers_linked'][$printer_id][] = $row_link;
                                if (!in_array($printer_id, $printers_id)) {
                                    $printers_id[] = $printer_id;
                                }
                            }
                        }
                    }
                }
            }

            $all_product_total_price_before_disc = $product_total_price_with_vat_before_disc + $product_total_price_without_vat_before_disc;

            $data['main']['product_total_price_without_vat'] = CommonFunctions::formatNumber($product_total_price_without_vat);
            $data['main']['product_total_price_with_vat'] = CommonFunctions::formatNumber($product_total_price_with_vat);
            $data['main']['product_total_price_ttc_with_vat'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat);
            
            $data['main']['product_total_price_without_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_without_vat_before_disc);
            $data['main']['product_total_price_with_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_with_vat_before_disc);
            
            $data['main']['all_product_total_price_before_disc'] = CommonFunctions::formatNumber($all_product_total_price_before_disc);

            $data['main']['product_total_price_ttc_with_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat_before_disc);
            
            $data['main']['product_total_price_with_vat_pos'] = CommonFunctions::formatNumber($product_total_price_with_vat_pos);
            $data['main']['product_total_price_ttc_with_vat_pos'] = CommonFunctions::formatNumber($product_total_price_with_vat);
            $data['main']['product_total_price_ttc_with_vat_before_disc_pos'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat_before_disc_pos);
            $data['main']['total_vat_amount_before_disc'] = CommonFunctions::formatNumber($total_vat_amount_before_disc);

            $data['printer_ids'] = $printers_id;
            $data['main']['invoice_total_quantity'] = CommonFunctions::formatNumber($data['main']['invoice_total_quantity'], 2);
            $data['main']['invoice_total_row_discount'] = CommonFunctions::formatNumber($inv_ttl_row_disc, 2);
            $data['main']['invoice_total_full_discount'] = CommonFunctions::formatNumber(($inv_disc_amount + $inv_ttl_row_disc), 2);    //total discount for both at whole invoice and at invoice rows
            $data['main']['discount_amount_ttc'] = CommonFunctions::formatNumber(($inv_sub_ttl_ttc * ($inv_disc_percentage / 100)), 2);
            $data['main']['Invoice_Sub_Total_ttc'] = CommonFunctions::formatNumber($inv_sub_ttl_ttc, 2);
            if (!is_null($fire_level))
                $data['main']['entry_ids'] = $entry_ids_arr;
        }

        //
        $data['main']['disc_class'] = empty($data['disc_items']) ? 'hidden' : '';
        $data['main']['disc_linked_class'] = empty($data['disc_items_linked']) ? 'hidden' : '';
        $data['main']['no_disc_class'] = empty($data['no_disc_items']) ? 'hidden' : '';
        $data['main']['no_disc_linked_class'] = empty($data['no_disc_items_linked']) ? 'hidden' : '';
        //
        $tmp_pay_cash = 0;
        $data['main']['pay_cash_amount'] = $data['main']['pay_check_amount'] = $data['main']['pay_credit_amount'] = 0;
        $data['main']['pay_cash_class'] = $data['main']['pay_check_class'] = $data['main']['pay_credit_class'] = 'hidden';
        $query = $this->db->query("SELECT 
                                            t.Transaction_Amount,
                                            t.Transaction_Reference,
                                            t.Account_ID,
                                            p.Account_Name AS P_Name,
                                            t.check_nb,t.due_date,t.value_date,t.user_ref,
                                             t.Transaction_Description
                                        FROM 
                                            tbl_accounting_transactions t
                                        inner JOIN 
                                            tbl_chart_of_accounts p
                                        ON 
                                            t.Account_ID = p.Account_ID
                                       WHERE 
                                             t.main_id = '" . $id . "'
                                        AND 
                                            t.main_type = 'inv'
                                        AND 
                                            t.Transaction_Reference in ('cash','check','credit')
                                        ");
        while ($row = $this->db->assoc($query)) {
            if (stripos($row['Transaction_Reference'], 'cash') !== false) {
                $tmp_pay_cash = $row['Transaction_Amount'];
                $data['main']['pay_cash_amount'] = CommonFunctions::formatNumber($tmp_pay_cash, 2);
                $data['main']['pay_cash_class'] = '';
            }if (stripos($row['Transaction_Reference'], 'check') !== false) {
                $data['main']['pay_check_amount'] = CommonFunctions::formatNumber($row['Transaction_Amount'], 2);
                $data['main']['pay_check_class'] = '';
            }if (stripos($row['Transaction_Reference'], 'credit') !== false) {
                $data['main']['pay_credit_amount'] = CommonFunctions::formatNumber($row['Transaction_Amount'], 2);
                $data['main']['pay_credit_class'] = '';
            }
        }
        $returned_cash = $cash_amount - $tmp_pay_cash;
        $data['main']['returned_cash'] = CommonFunctions::formatNumber($returned_cash);
//                echo"<pre>";die(print_r($data));
        //
        return $data;
    }

    //in case if want to merge identical invoice rows on print
    public function merge_identical_invoice_rows($data) {
        //in invoice case
        $data['Details'] = $this->internal_merge_rows($data['Details']);
        $data['DetailsLinked'] = $this->internal_merge_rows($data['DetailsLinked']);
        //below needed in order/kitchen case
        if (!empty($data['printers']))
            foreach ($data['printers'] as $indx => $prntr_inv_rows)
                $data['printers'][$indx] = $this->internal_merge_rows($prntr_inv_rows);
        if (!empty($data['printers_linked']))
            foreach ($data['printers_linked'] as $indx => $prntr_inv_rows)
                $data['printers_linked'][$indx] = $this->internal_merge_rows($prntr_inv_rows);
        //
        return $data;
    }

    private function internal_merge_rows($arr_rows) {
        if (empty($arr_rows))
            return $arr_rows;
        $idntcl_flds = array('Invoice_ID_Auto', 'Product_ID', 'vat_percent', 'expiry_date', 'product_description', 'Product_Discount', 'Product_Net_Price'
            , 'UOM_ID', 'lot_nb', 'serial_nb', 'TAG', 'add_ons', 'hold');
        $grp_flds = array('Item_Quantity_Current', 'vat_amount', 'Product_Total_Price_TTC', 'Discount_Amount', 'Product_Total_Price', 'Product_Total_Price_After_Disc'
            , 'Product_Total_Price_After_Disc_TTC', 'total_with_vat', 'Product_Total_Price_TTC_Before_Disc', 'Product_Total_Price_Before_Disc');
        $sep = '|#|$|#|';
        $idntcl_rows = array();
        foreach ($arr_rows as $indx => $row) {
            $idntcl_str = '';
            foreach ($idntcl_flds as $fld)
                $idntcl_str .= $row[$fld] . $sep;
            $idntcl_rows[$idntcl_str][] = $indx;
        }
        //if there is no identical
        if (count($idntcl_rows) == count($arr_rows))
            return $arr_rows;
        //
        $new_rows = array();
        $count_var = 0;
        foreach ($idntcl_rows as $indx_rows) {
            $tmp_row = $arr_rows[$indx_rows[0]];
            $tmp_row['Count'] = ++$count_var;
            $count_idntcl = count($indx_rows);
            if ($count_idntcl > 1) {
                for ($i = 1; $i < $count_idntcl; $i++) {
                    $idntncl_row = $arr_rows[$indx_rows[$i]];
                    foreach ($grp_flds as $fld) {
                        $tmp_val = doubleval(str_replace(',', '', $tmp_row[$fld])) + doubleval(str_replace(',', '', $idntncl_row[$fld]));
                        $tmp_row[$fld] = CommonFunctions::formatNumber($tmp_val);
                    }
                }
            }
            $new_rows[] = $tmp_row;
        }
        return $new_rows;
    }

    public function movement_control_total() {
        $cond = ' ';
        $type = $this->info['type'];
        $from_date = $this->info['Date_From'];
        $to_date = $this->info['Date_To'];
        $is_actual = $this->info['is_actual'];
        $person_id = $this->info['person'];
        $foreign = $this->info['foreign'];
        $data = array("net_total" => 0, "vat" => 0, "subtotal" => 0);
        //        if (isset($foreign) && $foreign != 'both') {
        //            $cond.= ' and Country_ID ' . ($foreign == 0 ? ' = ' : ' <> ') . '"' . smc_session()['org_detail']['Organization_Country'] . '"';
        //        }
        if ($type == 'inv') {
            if (is_numeric($person_id))
                $cond .= ' and i.Customer_ID = "' . $person_id . '"';
            if (isset($foreign) && $foreign != 'both') {
                $cond .= ' and Customer_Country_ID ' . ($foreign == 0 ? ' = ' : ' <> ') . '"' . smc_session()['org_detail']['Organization_Country'] . '"';
            }
            if (!empty($this->info['branch_id']))
                $cond .= ' and i.branch_id ="' . $this->info['branch_id'] . '"';
            $query = $this->db->query('select sum(i.Invoice_Net_Total*i.current_rate) as net_total ,
                sum(i.Invoice_VAT*i.current_rate) as vat,
                sum(i.Invoice_Sub_Total*i.current_rate) as subtotal
                from tbl_invoices i join tbl_customers c on c.Customer_ID = i.Customer_ID
                where i.Invoice_Date between "' . $from_date . '" and "' . $to_date . '"
                and i.is_actual = "' . $is_actual . '"   and is_committed = 1  ' . (!empty($this->info['sales_man_id']) ? ' and i.Sales_ID = "' . $this->info['sales_man_id'] . '" ' : ' ') . $cond);
        } elseif ($type == 'pur') {
            if (is_numeric($person_id))
                $cond .= ' and p.Supplier_ID = "' . $person_id . '"';
            if (isset($foreign) && $foreign != 'both') {
                $cond .= ' and Supplier_Country ' . ($foreign == 0 ? ' = ' : ' <> ') . '"' . smc_session()['org_detail']['Organization_Country'] . '"';
            }
            if (!empty($this->info['branch_id']))
                $cond .= ' and p.branch_id ="' . $this->info['branch_id'] . '"';
            $query = $this->db->query('select sum(p.Purchase_Net_Total*p.current_rate) as net_total ,
                sum(p.Purchase_VAT*p.current_rate) as vat,
                sum(p.Purchase_Sub_Total*p.current_rate) as subtotal
                from tbl_inventory_purchases p join tbl_stock_suppliers s on s.Supplier_ID = p.Supplier_ID
                where p.Purchase_Date between "' . $from_date . '" and "' . $to_date . '"
                  and p.is_actual = "' . $is_actual . '"     ' . $cond);
        } else {
            if (!empty($person_id))
                $cond .= ' and r.Person_ID = "' . $person_id . '"';
            if (isset($foreign) && $foreign != 'both') {
                $cond .= ' and ' . ($type == 'rin' ? 'Customer_Country_ID' : 'Supplier_Country') . ($foreign == 0 ? ' = ' : ' <> ') . '"' . smc_session()['org_detail']['Organization_Country'] . '"';
            }
            if (!empty($this->info['branch_id']))
                $cond .= ' and r.branch_id ="' . $this->info['branch_id'] . '"';
            $ret_type = $type == 'rin' ? 1 : 0;
            $join_cond = $type == 'rin' ? ' join tbl_customers c on c.Customer_ID = r.Person_ID ' : ' join tbl_stock_suppliers s on s.Supplier_ID = r.Person_ID ';
            $query = $this->db->query('select sum(r.Return_Net_Total*r.current_rate) as net_total ,
                sum(r.Invoice_VAT*r.current_rate) as vat, 
                sum(r.Return_Invoice_Total*r.current_rate) as subtotal 
                from tbl_accounting_return_invoices r ' . $join_cond . '
                where r.Return_Invoice_Date between "' . $from_date . '" and "' . $to_date . '" 
                    and r.Is_Customer_Invoice = "' . $ret_type . '"  and r.Is_Actual = "' . $is_actual . '" ' . (!empty($this->info['sales_man_id']) ? ' and r.Sales_ID = "' . $this->info['sales_man_id'] . '" ' : ' ') . $cond);
        }
        $row = $this->db->assoc($query);
        //        die(print_r($row));
        if (!is_null($row['net_total'])) {
            $data['net_total'] = $row['net_total'];
            $data['vat'] = $row['vat'];
            $data['subtotal'] = $row['subtotal'];
        }
        //        die(print_r($data));
        return $data;
    }

    public function deleteSalesInvoice($id_arr) {
        if (smc_session()['year_closed'] == 1) {
            $error = array();
            $error[0] = CommonLanguage::getMessage('delete_year_alert');
            return $error;
        }
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        foreach ($id_arr as $id) {
            $query = $this->db->query('select Is_Closed from tbl_invoices where Invoice_ID_Auto = "' . $id . '" and table_id <> 0');
            $row_nb = $this->db->rowsno($query);
            if ($row_nb > 0) {
                $is_closed = $this->db->assoc($query)['Is_Closed'];
                if ($is_closed == 0) {
                    $error[0] = CommonLanguage::getMessage('closed_table_alert');
                    return $error;
                }
            }
            $query = $this->db->query('select Invoice_Date,is_actual
                from tbl_invoices where Invoice_ID_Auto = "' . $id . '"');
            $row = $this->db->assoc($query);
            $check = CommonFunctions::check_lock_data(['type' => 'invoice', 'start_date' => $row['Invoice_Date'], 'is_actual' => $row['is_actual']]);
            if ($check !== '') {
                continue;
            }
            $query = $this->db->query('SELECT * FROM `tbl_invoice_payments` WHERE inv_pur_id = "' . $id . '" and type in ("rec","cmjv","cre")');
            $row_nb = $this->db->rowsno($query);
            if ($row_nb > 0) {
                $error[0] = CommonLanguage::getMessage('related_to_payment');
                return $error;
            }
            //            die();
            $arr = ['type' => 'inv', 'main_id' => $id, 'action' => 2];
            CommonFunctions::add_user_log($arr);
            //
            $this->db->prepare_Stmt('delete from tbl_accounting_transactions where main_id= ? and main_type="inv"', [&$id]);
            $this->edit_old_details_qty_cost($id);
            $this->db->prepare_Stmt("DELETE criteria FROM  tbl_invoice_product_criteria criteria
                                inner join tbl_invoice_products_details details on details.Entery_ID = criteria.Entery_ID
                                inner join tbl_invoices invoices on invoices.Invoice_ID_Auto = details.Invoice_ID_Auto 
                                where invoices.Invoice_ID_Auto = ?", [&$id]);
            $this->db->prepare_Stmt("DELETE add_ons FROM  tbl_invoice_product_add_ons add_ons
                                inner join tbl_invoice_products_details details on details.Entery_ID = add_ons.Entery_ID
                                inner join tbl_invoices invoices on invoices.Invoice_ID_Auto = details.Invoice_ID_Auto 
                                where invoices.Invoice_ID_Auto = ?", [&$id]);
            $this->db->prepare_Stmt('delete from tbl_invoice_products_details where Invoice_ID_Auto= ? ', [&$id]);
            $this->db->prepare_Stmt('delete from tbl_invoice_shipping where Invoice_ID_Auto = ? ', [&$id]);
            $this->db->prepare_Stmt('delete from tbl_invoices  where Invoice_ID_Auto= ? ', [&$id]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function edit_old_details_qty_cost($inv_auto_id) {
//        echo"<pre>";die(print_r($this->info));
        $today = Date::getToday();
        $option_arr = array();
        $query = $this->db->query('select p.invoice_detail_id,p.product_id,p.UOM_ID as uom_id,
            p.option_quantity as qty
            from tbl_invoice_product_options p
            join tbl_invoice_products_details d on d.Entery_ID = p.invoice_detail_id 
            where d.Invoice_ID_Auto = "' . $inv_auto_id . '"');
        while ($row = $this->db->assoc($query)) {
            $option_arr[$row['invoice_detail_id']][] = $row;
        }
        $depot_id = 0;

        $query = $this->db->query("SELECT 
                                        p.Product_ID,
                                        p.Item_Quantity_Current as Current_Quantity,
                                        p.Product_Quantity  as Quantity,
                                        p.UOM_ID,p.qty_link,
                                        p.unit_cost,p.Product_Net_Price,
                                        i.Invoice_Currency AS Currency_ID,
                                        p.depot_id as Depot_ID,
                                        i.current_rate,
                                        i.date_time,
                                        i.invoice_prefix, i.Customer_ID,
                                        i.Invoice_ID,i.created_logged_id,i.date_created,p.expiry_date,
                                        i.invoice_app_id,i.app_branch_id,i.app_user_id,p.lot_nb,p.serial_nb,pr.is_service,p.Entery_ID
                                    FROM 
                                        tbl_invoice_products_details p
                                    join tbl_invoices i on i.Invoice_ID_Auto = p.Invoice_ID_Auto
                                    join tbl_stock_products pr on pr.Product_ID = p.Product_ID
                                    WHERE 
                                        p.Invoice_ID_Auto = '" . $inv_auto_id . "' 
                                            and (isnull(p.Delivery_Report_ID) or p.Delivery_Report_ID = 0)
                ");
        $row_nb = $this->db->rowsno($query);
        if ($row_nb > 0) {
            while ($row = $this->db->assoc($query)) {
                $depot_id = $row['Depot_ID'];
                //            $old_date_time = $row['date_time'];
                //                $sub_cost = $row['link_id'] == 0 ? $row['unit_cost'] : CommonBusiness::viewCurrentProductCost($row['sub_product_id']);
                $expiry_date = !empty($row['expiry_date']) ? $row['expiry_date'] : null;
                $lot_nb = !empty($row['lot_nb']) ? $row['lot_nb'] : '';
                $serial_nb = !empty($row['serial_nb']) ? $row['serial_nb'] : '';
                $costdata = [
                    "Product_ID" => '', //$row['sub_product_id'],
                    "Quantity" => '', //$row['Quantity'],
                    "Unit_Cost" => '', //$sub_cost,
                    "unit_price" => $row['Product_Net_Price'],
                    "Currency_ID" => $row['Currency_ID'],
                    "date_time" => $row['date_time'],
                    "date_time_now" => date("Y-m-d H:i:s"),
                    "current_rate" => $row['current_rate'],
                    "depot_id" => $row['Depot_ID'],
                    "trans_date" => $today,
                    "current_quantity" => '', //$row['Current_Quantity'],
                    "uom_id" => '', //$row['UOM_ID'],
                    "is_actual" => 0,
                    "expiry_date" => $expiry_date,
                    "lot_nb" => $lot_nb,
                    "serial_nb" => $serial_nb,
                    "main_id" => $inv_auto_id,
                    "is_service" => $row['is_service'],
                    "main_nb" => $row['invoice_prefix'] . $row['Invoice_ID'],
                    "customer_id" => $row['Customer_ID']
                ];
                $option_arr_temp = !empty($option_arr[$row['Entery_ID']]) ? $option_arr[$row['Entery_ID']] : array();

                $product_links = CommonBusiness::get_product_links($row['Product_ID'], $row['UOM_ID'], $row['Quantity'], $row['Current_Quantity'], '-', 0, $option_arr_temp);
                $is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $row['Product_ID'] . '" ');
                $is_rate_row = $this->db->assoc($is_rate_query); 
                $is_rate_type_one = $is_rate_row['is_rate_type_one'];
                $is_rate_type_two = $is_rate_row['is_rate_type_two'];
                $rate_type_one = smc_session()['default_setting']['rate_type_one'];
                $rate_type_two = smc_session()['default_setting']['rate_type_two'];
    
                $effect_qty_link_product  = $is_rate_row['effect_qty_link_product'];

                
                
                foreach ($product_links as $link) {
                    $link_is_rate_query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Product_ID = "' . $link['Product_ID'] . '" ');
                    $link_is_rate_row = $this->db->assoc($link_is_rate_query); 
                    $link_is_rate_type_one = $link_is_rate_row['is_rate_type_one'];
                    $link_is_rate_type_two = $link_is_rate_row['is_rate_type_two'];
    
    
                    $costdata["Quantity"] = $link['Quantity'];
                    $costdata["current_quantity"] = $link['current_quantity'];

                    if($is_rate_type_one == 1 && $link_is_rate_type_one == 1 && $rate_type_one > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_one)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"];

                    }
                    if($is_rate_type_two == 1 && $link_is_rate_type_two == 1  && $rate_type_two > 0 && $link['operation'] == '-'){
                        $costdata["Quantity"] = abs($costdata["Quantity"] - (($costdata["Quantity"]*$rate_type_two)/100));
                        $costdata["current_quantity"] = $costdata["Quantity"];
                    }

                    if($effect_qty_link_product == 1){
                        $costdata["Quantity"] = $row['qty_link'];
                        $costdata["current_quantity"] = $row['qty_link'];
                    }
    
    
                    $costdata["Product_ID"] = $link['Product_ID'];
                    $costdata["uom_id"] = $link['uom_id'];
                    $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                    if (!empty($link['is_main_prdct']))
                        $costdata['Unit_Cost'] = $row['unit_cost'];
                    else {
                        $cost = CommonBusiness::viewCurrentProductCost($link['Product_ID']);
                        $costdata['Unit_Cost'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $row['Currency_ID'], $cost);
                    }
                    //                    $cost = CommonBusiness::viewCurrentProductCost($link['Product_ID']);
                    //                    $costdata['Unit_Cost'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $row['Currency_ID'], $cost);
                    //                    echo"<pre>";print_r($costdata);
                    self::updateLinkQuantities($costdata, "delete_invoice", ($link['operation'] == '+' ? '-' : '+'));
                }
                //                    die();
                //                $cost = self::updateLinkQuantities($costdata, "edit_invoice_old", ($row['operation'] == '+' ? '-' : '+'));
            }
            CommonBusiness::update_trans_record_current('inv', $inv_auto_id);
        }
        return array("Depot_ID" => $depot_id);
    }

    public function getUserInvoices() {
        $condition = empty($this->info['user']) ? '' : ' and user = "' . $this->info['user'] . '" ';
        $condition .= ' AND date_created >= "' . $this->info['From_Date'] . '" AND date_created <= "' . $this->info['To_Date'] . '" ';
        if (isset($this->info['salesman']) && $this->info['salesman'] != '') {
            $condition .= ' and Sales_ID = "' . $this->info['salesman'] . '"';
        }
        if (!empty($this->info['type'])) {
            $condition .= ' and type = "' . $this->info['type'] . '"';
        }
        //        if ($this->info['is_actual'] == 0) {
        $condition .= ' and is_actual = 0 ';
        //        }
        if (!empty($this->info['class_id'])) {
            $condition .= ' AND class_id ="' . $this->info['class_id'] . '"';
        }
        if (!empty($this->info['branch_id'])) {
            $condition .= ' AND branch_id ="' . $this->info['branch_id'] . '" ';
        }
        if (!empty($this->info['unpaid_inv'])) {
            $condition .= ' AND Invoice_Status <> 2 ';
        }
        $data = array();
        $query = $this->db->query('select *
                                   from user_invoices
                                   where is_committed = 1
        ' . $condition);
        while ($row = $this->db->assoc($query)) {
            $row['current_total'] = CommonFunctions::formatNumber($row['total'] * $row['current_rate']);
            $row['paid_amount'] = CommonFunctions::formatNumber($row['total_cash'] * $row['current_rate']);
            $row['current_type'] = $row['type'] == 'Invoice' ? 'I' : 'R';
            $data[] = $row;
        }
        return $data;
    }
    public function getUserInvoicesTotal() {
        $condition = empty($this->info['user']) ? '' : ' and user = "' . $this->info['user'] . '" ';
        $condition .= ' AND date_created >= "' . $this->info['From_Date'] . '" AND date_created <= "' . $this->info['To_Date'] . '" ';
        if (isset($this->info['salesman']) && $this->info['salesman'] != '') {
            $condition .= ' and Sales_ID = "' . $this->info['salesman'] . '"';
        }
        if (!empty($this->info['type'])) {
            $condition .= ' and type = "' . $this->info['type'] . '"';
        }
        //        if ($this->info['is_actual'] == 0) {
        $condition .= ' and is_actual = 0 ';
        //        }
        if (!empty($this->info['class_id'])) {
            $condition .= ' AND class_id ="' . $this->info['class_id'] . '"';
        }
        if (!empty($this->info['branch_id'])) {
            $condition .= ' AND branch_id ="' . $this->info['branch_id'] . '" ';
        }
        if (!empty($this->info['unpaid_inv'])) {
            $condition .= ' AND Invoice_Status <> 2 ';
        }
        $data = array();
        $query = $this->db->query($x ='select sum(total) as total , sum(total_cash) as total_cash,current_rate,type
                                   from user_invoices
                                   where is_committed = 1
        ' . $condition);
        $row = $this->db->assoc($query);
            $row['current_total'] = CommonFunctions::formatNumber($row['total'] * $row['current_rate']);
            $row['paid_amount'] = CommonFunctions::formatNumber($row['total_cash'] * $row['current_rate']);
            $row['current_type'] = $row['type'] == 'Invoice' ? 'I' : 'R';
          
        return $row;
    }


    public function getTotalSoldItems() {
        $condition = ' where current_year_id="' . $this->year_id . '"';
        if (!empty($this->info['From_Date'])) {
            $condition .= ' AND u.date_created between "' . $this->info['From_Date'] . '" AND "' . $this->info['To_Date'] . '"';
        }
        if (!empty($this->info['From_Date_invoice'])) {
            $condition .= ' AND u.Date between "' . $this->info['From_Date_invoice'] . '" AND "' . $this->info['To_Date_invoice'] . '"';
        }
        if (!empty($this->info['users'])) {
            $condition .= ' AND u.Logged_ID in (' . $this->info['users'] . ')';
        }
        if (is_numeric($this->info['customer_id'])) {
            $condition .= ' AND u.Customer_ID = "' . $this->info['customer_id'] . '"';
        }
        //        if ($this->info['is_actual'] == 0) {
        $condition .= ' and u.is_actual = 0 ';
        //        }
        $gourp_by = ' GROUP BY ' . (empty($this->info['is_day']) ? '' : 'u.Date,') . 'u.Product_ID,u.Currency_ID';
        $data = array();
        $data_uniq = array();
        $string_query = '';
        if ($this->info['return'] == 0) {
            $string_query = 'select Date,SUM(Quantity) as total_qty,SUM(Product_Total_Price+vat_amount) as total_price,
            Item_Name,Code,Logged_ID,Currency_Symbol,UOM_Name from product_mov_invoice u';
        } else {
            $string_query = 'select Product_Name,u.*,um.UOM_Name,
            p.Product_Name as Item_Name,p.Product_Code as Code,c.Currency_Symbol,
            SUM(Quantity) as total_qty,SUM(Product_Total_Price) as total_price 
            from
            (select i.Customer_ID as Customer_ID,i.date_created,`d`.`Product_ID`,`d`.`Product_Quantity` AS `Quantity`,(`d`.`Product_Total_Price` + d.vat_amount) AS `Product_Total_Price`,
            `i`.`Invoice_Date` AS `Date`,`i`.`Invoice_Currency` AS `Currency_ID`,i.current_year_id,i.Logged_ID ,i.created_logged_id,i.is_actual 
            from `tbl_invoice_products_details` `d` 
            join `tbl_invoices` `i` on `i`.`Invoice_ID_Auto` = `d`.`Invoice_ID_Auto`
            union all
            select i.Person_ID as Customer_ID,i.date_created,d.Product_ID,(d.Return_Product_Quantity *(-1)) as Quantity,
            ((d.Return_Product_Total + d.vat_amount) * -1) as Product_Total_Price,i.Return_Invoice_Date AS `Date`,i.Currency_ID,i.current_year_id,
            i.Logged_ID,i.created_logged_id,i.Is_Actual as is_actual
            from tbl_accounting_return_items d
            join tbl_accounting_return_invoices i on d.Return_Invoice_ID = i.Return_Invoice_ID) u 
            join tbl_stock_products p on u.Product_ID = p.Product_ID 
            join tbl_common_currency c on c.Currency_ID = u.Currency_ID 
            left join tbl_stock_uom um 
            on um.UOM_ID = p.UOM_ID ';
        }
        $query = $this->db->query($string_query . $condition . $gourp_by);
        while ($row = $this->db->assoc($query)) {
            if (empty($this->info['is_day']))
                $data[] = $row;
            else {
                $data[$row['Date']][] = $row;
                //here if all specific date is with same currency or unit then put it at header not at each row
                if (!isset($data_uniq[$row['Date']]))
                    $data_uniq[$row['Date']] = array('curr' => $row['Currency_Symbol'], 'uom' => $row['UOM_Name']);
                else {
                    if ($data_uniq[$row['Date']]['curr'] != $row['Currency_Symbol'])
                        $data_uniq[$row['Date']]['curr'] = '';
                    if ($data_uniq[$row['Date']]['uom'] != $row['UOM_Name'])
                        $data_uniq[$row['Date']]['uom'] = '';
                }
            }
        }
        if (!empty($this->info['is_day']))
            $data['data_uniq'] = $data_uniq;
        return $data;
    }

    public function get_total_sold_items_totals($with_return, $from_date, $to_date, $users, $is_actual, $customer_id, $is_day, $from_date_invoice, $to_date_invoice, $branch_id, $category_id, $sales_man) {
        $cond = ' where current_year_id="' . $this->year_id . '"';
        if (!empty($from_date) && !empty($to_date)) {
            $cond .= ' AND u.date_created between "' . $from_date . '" AND  "' . $to_date . '"';
        }
        if (!empty($from_date_invoice) && !empty($to_date_invoice)) {
            $cond .= ' AND u.Date between "' . $from_date_invoice . '" AND  "' . $to_date_invoice . '"';
        }
        if (!empty($users)) {
            $cond .= ' AND u.Logged_ID in (' . $users . ')';
        }
        if (is_numeric($customer_id)) {
            $cond .= ' AND u.Customer_ID = "' . $customer_id . '"';
            if (!empty($this->info['customer_branch_id']))
                $cond .= ' and customer_branch_id = "' . $this->info['customer_branch_id'] . '"';
        }
        if (!empty($branch_id)) {
            $cond .= ' AND u.branch_id = "' . $branch_id . '"';
        }
        if (!empty($sales_man)) {
            $cond .= ' AND u.Sales_ID = "' . $sales_man . '"';
        }
        if (!empty($category_id)) {
            $cond .= ' AND Category_ID = "' . $category_id . '"';
        }
        if (!empty($this->info['customer_group_id'])) {
            $cust_ids = array();
            $query = $this->db->prepare_Stmt('select Customer_ID from tbl_customers 
                where customer_group_id = ?', [$this->info['customer_group_id']]);
            while ($row = $this->db->assoc($query))
                $cust_ids[] = $row['Customer_ID'];
            if (!empty($cust_ids))
                $cond .= ' AND Customer_ID in (' . implode(',', $cust_ids) . ') ';
            else
                $cond .= ' and 1=2 ';
        }
        if ($is_actual == 0) {
            $cond .= ' and u.is_actual = "' . $is_actual . '"';
        }
        $gourp_by = empty($is_day) ? '' : ' GROUP BY u.Date';
        if ($with_return)
            $query_str = '
            select sum(Product_Total_Price * current_rate) as sub_total_price,
             sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
             0 as total_qty_link,
            sum((Quantity/if(p.default_view_uom_id=0,1,p.default_view_rate))) as total_quantity,sum(vat_amount * current_rate) as total_vat_price,
            u.Date,u.is_actual,u.Sales_ID,u.branch_id,p.Category_ID from 
                (select i.Customer_ID  as Customer_ID,i.date_created,`d`.`Product_ID`,`d`.`Product_Quantity` AS `Quantity`,
                `d`.`Product_Total_Price` AS `Product_Total_Price`,`d`.`vat_amount` AS `vat_amount`,`i`.`Invoice_Date` AS `Date`,
                `i`.`Invoice_Currency` AS `Currency_ID`,i.current_year_id,i.Logged_ID ,
                i.created_logged_id,i.is_actual ,i.current_rate,i.Sales_ID,i.branch_id,i.customer_branch_id,
                d.vat2_amount
                from `tbl_invoice_products_details` `d` join `tbl_invoices` `i` 
                on `i`.`Invoice_ID_Auto` = `d`.`Invoice_ID_Auto`
                where i.is_committed = 1
            union all
                select i.Person_ID  as Customer_ID,i.date_created,d.Product_ID,(d.Return_Product_Quantity *(-1)) as Quantity,
                (d.Return_Product_Total * (-1)) as Product_Total_Price,(`d`.`vat_amount` * (-1)) AS `vat_amount`,i.Return_Invoice_Date AS `Date`,
                i.Currency_ID,i.current_year_id,i.Logged_ID,i.created_logged_id,i.Is_Actual as is_actual,i.current_rate,i.Sales_ID,i.branch_id,i.customer_branch_id,
                (`d`.`vat2_amount` * (-1)) AS `vat2_amount`
                from tbl_accounting_return_items d join tbl_accounting_return_invoices i 
                on d.Return_Invoice_ID = i.Return_Invoice_ID )
            as u join tbl_stock_products p on u.Product_ID = p.Product_ID ';
        else {
            $query_str = 'select u.Date, sum(Product_Total_Price * current_rate) as sub_total_price,
                sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
             sum(qty_link) as total_qty_link,
                sum(vat_amount * current_rate) as total_vat_price,
                sum(def_view_qty) as total_quantity
                from product_movement_invoice u';
            $cond .= ' and is_committed = 1';
        }
        $query = $this->db->query($query_str . $cond . $gourp_by);
        //        die(print_r($query_str . $cond . $gourp_by));
        if (empty($is_day)) {
            $row = $this->db->assoc($query);
            if (empty($row))
                $totals = $sub_total = $vat_total = $total_quantity = $total_qty_link = $vat1_total = $vat2_total = $total_with_vat = 0;
            else {
                //                $sub_total = ($row['sub_total_price']);
                //                $vat_total = ($row['total_vat_price']);
                $totals = CommonFunctions::formatNumber($row['sub_total_price'] + $row['total_vat_price']);
                $sub_total = CommonFunctions::formatNumber($row['sub_total_price']);
                $vat_total = CommonFunctions::formatNumber($row['total_vat_price']);
                $vat1_total = CommonFunctions::formatNumber($row['vat1_total']);
                $vat2_total = CommonFunctions::formatNumber($row['vat2_total']);
                $total_with_vat = CommonFunctions::formatNumber($row['total_with_vat']);
                $total_quantity = CommonFunctions::formatNumber($row['total_quantity']);
                $total_qty_link = $row['total_qty_link'];
            }
            return array('total' => $totals, 'sub_total' => $sub_total,
                'vat_total' => $vat_total, 'total_quantity' => $total_quantity,
                'vat1_total' => $vat1_total, 'vat2_total' => $vat2_total, 'total_with_vat' => $total_with_vat,'total_qty_link' => $total_qty_link );
        }
        $arr = array();
        while ($row = $this->db->assoc($query)) {
            //            $sub_total = ($row['sub_total_price']);
            //            $vat_total = ($row['total_vat_price']);
            $totals = CommonFunctions::formatNumber($row['sub_total_price'] + $row['total_vat_price']);
            $sub_total = CommonFunctions::formatNumber($row['sub_total_price']);
            $vat_total = CommonFunctions::formatNumber($row['total_vat_price']);
            $vat1_total = CommonFunctions::formatNumber($row['vat1_total']);
            $vat2_total = CommonFunctions::formatNumber($row['vat2_total']);
            $total_with_vat = CommonFunctions::formatNumber($row['total_with_vat']);
            $total_quantity = CommonFunctions::formatNumber($row['total_quantity']);
            $total_qty_link = $row['total_qty_link'];
            $arr[$row['Date']] = array('total' => $totals, 'sub_total' => $sub_total,
                'vat_total' => $vat_total, 'total_quantity' => $total_quantity,
                'vat1_total' => $vat1_total, 'vat2_total' => $vat2_total,'total_qty_link' => $total_qty_link , 'total_with_vat' => $total_with_vat);
        }
        return $arr;
    }

    public function reorderInvNum($from_date, $is_actual) {
        $year_id = $is_actual ? $this->year_id_actual : $this->year_id;
        if (!$this->stop_transaction_start_end)
            $this->db->query("START TRANSACTION");
        $query_prefix = $this->db->query('select distinct invoice_prefix from tbl_invoices');
        while ($row_prefix = $this->db->assoc($query_prefix)) {
            $inv_cond = " and current_year_id = '" . $year_id . "' and is_actual = '" . $is_actual . "'
                    and invoice_prefix = '" . $row_prefix['invoice_prefix'] . "'";
            //here get last invoice in previous date period
            $query = $this->db->query("SELECT Invoice_ID FROM tbl_invoices WHERE Invoice_Date < '{$from_date}' {$inv_cond}
				ORDER BY Invoice_ID desc limit 1");
            $row = $this->db->assoc($query);
            $new_inv = empty($row['Invoice_ID']) ? 0 : $row['Invoice_ID'];
            //if want to depend on first exist invoice regardless specified date
            if (empty($new_inv) && !empty($_POST['first_exist_nb'])) {
                $query = $this->db->query("SELECT Invoice_ID FROM tbl_invoices WHERE Invoice_Date >= '{$from_date}' {$inv_cond}
				ORDER BY Invoice_ID asc limit 1");
                $row = $this->db->assoc($query);
                $new_inv = (empty($row['Invoice_ID']) ? 0 : ($row['Invoice_ID'] - 1));
            }
            //
            if (empty($new_inv) && !empty($_POST['first_invoice_nb']) && $_POST['first_invoice_nb'] > 0)
                $new_inv = $_POST['first_invoice_nb'] - 1;
            //
            $this->db->prepare_Stmt("set @inv_nb = '" . $new_inv . "'; ");
            $this->db->prepare_Stmt("UPDATE tbl_invoices SET
                        is_main_transfer = if((@inv_nb+1)=Invoice_ID, is_main_transfer, 0)
                        , Invoice_ID = (@inv_nb:=@inv_nb+1)
                    WHERE Invoice_Date >='" . $from_date . "' {$inv_cond}  ORDER BY Invoice_Date, Invoice_ID_Auto ");
            $this->db->prepare_Stmt('update tbl_accounting_transactions t join tbl_invoices i 
                on t.main_id = i.Invoice_ID_Auto and t.main_type = "inv"
                set t.main_nb = i.Invoice_ID  ');
            //            $query = $this->db->query("SELECT Invoice_ID_Auto,Invoice_ID 
            //            FROM tbl_invoices WHERE Invoice_Date >='" . $from_date . "' {$inv_cond}
            //            ORDER BY Invoice_Date, Invoice_ID_Auto ");
            //            while ($row = $this->db->assoc($query)) {
            //                $new_inv++;
            //                if ($row['Invoice_ID'] != $new_inv) {
            //                    $up = [&$new_inv, &$row['Invoice_ID_Auto']];
            //                    $this->db->prepare_Stmt("UPDATE tbl_invoices SET Invoice_ID = ?,
            //                        is_main_transfer = 0 WHERE Invoice_ID_Auto = ? ", $up);
            //                    $this->db->prepare_Stmt('update tbl_accounting_transactions set main_nb = ? where main_id = ? and main_type = "inv"', $up);
            //                }
            //            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function get_total_sales_purchase_invoices($IsVendor, $From_Date = null, $To_Date = null, $is_actual, $customer_supplier_id, $branch_id = null, $print_filter = '') {
        $cond = '';
        //        $IsVendor = $IsVendor === 'true' ? 1 : 0;
        //  echo $IsVendor.'===';
        $current_year = $this->year_id;
        $data_set = [
            &$current_year,
            &$is_actual
        ];
        if (!empty($From_Date) && !empty($To_Date)) {
            $data_set[] = &$From_Date;
            $data_set[] = &$To_Date;
            $cond .= $IsVendor == 0 ? " and Invoice_Date between ? and  ? " : " and Purchase_Date between ? and  ? ";
        }
        if (!empty($customer_supplier_id)) {
            $cond .= $IsVendor == 0 ? ' and customers.Customer_ID = "' . $customer_supplier_id . '" ' : ' and suppliers.Supplier_ID = "' . $customer_supplier_id . '" ';
            if (!empty($_GET['customer_branch_id']) && $IsVendor == 0)
                $cond .= ' and customer_branch_id = "' . $_GET['customer_branch_id'] . '"';
        }

        
        if ($IsVendor == 0) {
            if($this->permissions->hasPermission('Branches')){
                $cond .= !empty($branch_id) ? ' and inv.branch_id ="' . ($branch_id) . '"' : '';
            }else{
                $cond .= ' and inv.branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
            }
        }else{
            if($this->permissions->hasPermission('Branches')){
                $cond .= !empty($branch_id) ? ' and pur.branch_id ="' . ($branch_id) . '"' : '';
            }else{
                $cond .= ' and pur.branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
            }

        }
    
        if (!empty($this->info['salesman_id']) && $IsVendor == 0)
            $cond .= " and Sales_ID = '" . $this->info['salesman_id'] . "' ";
        if (!empty($this->info['invoice_type_id']) && $IsVendor == 0)
            $cond .= " and invoice_type_id = '" . $this->info['invoice_type_id'] . "' ";
        if (!empty($this->info['depot_id']))
            $cond .= " and Depot_ID = '" . $this->info['depot_id'] . "' ";
        if (!empty($this->info['group_id']))
            $cond .= " and  " . ($IsVendor == 0 ? 'customer_group_id' : 'supplier_group_id') . " = '" . $this->info['group_id'] . "' ";
        if (!empty($this->info['class_id']))
            $cond .= " and " . ($IsVendor == 0 ? 'customer_group_id' : 'supplier_class_id') . " = '" . $this->info['class_id'] . "' ";
        if ($print_filter !== '')
            $cond .= " and is_printed_invoice = '" . $print_filter . "' ";
        if (!empty($this->info['search_note'])) {
            $cond.=' and Invoice_Description like "%' . $this->info['search_note'] . '%" ';
        }
        $default_curr = CurrencyFactory::getDefaultCurrency();
        $exchange_rate = CurrencyFactory::getLastExRate($default_curr);
        $default_symbol = CurrencyFactory::getCurrencySymbol($default_curr);
        $local_symbol = CurrencyFactory::getLocalCurrencySymbol();
        if ($IsVendor == 0) {
            $cond .= ' and is_committed = 1';
            $query = $this->db->prepare_Stmt('select inv.Invoice_Date as date,inv.current_rate,
                    sum(inv.Invoice_Net_Total*inv.current_rate) as local_total,sum(if(' . $default_curr . ' = Invoice_Currency, (inv.Invoice_Net_Total), 
                    ((inv.Invoice_Net_Total*inv.current_rate)/' . $exchange_rate . '))) as default_total,
                        
  sum(inv.Invoice_Sub_Total*inv.current_rate) as local_sub_total,sum(if(' . $default_curr . ' = Invoice_Currency, (inv.Invoice_Sub_Total), 
                    ((inv.Invoice_Sub_Total*inv.current_rate)/' . $exchange_rate . '))) as default_sub_total,
                        
                     inv.Invoice_Currency as currency_id,customers.customer_group_id,customers.customer_class_id
            from tbl_invoices inv
            inner join tbl_customers customers on customers.Customer_ID = inv.Customer_ID
            where inv.current_year_id= ? and  inv.is_actual = ? ' . $cond, $data_set);
        } else {
            if (isset($_GET['is_noqty']))
                $cond .= ' and disable_qty = "' . $_GET['is_noqty'] . '"';
            $query = $this->db->prepare_Stmt('select pur.Purchase_Date as date,pur.current_rate, 
                sum(pur.Purchase_Net_Total*pur.current_rate) as local_total ,
                    sum(if(' . $default_curr . ' = pur.Currency_ID, (pur.Purchase_Net_Total),((pur.Purchase_Net_Total*pur.current_rate)/' . $exchange_rate . '))) as default_total ,
               sum(pur.Purchase_Sub_Total*pur.current_rate) as local_sub_total ,
                    sum(if(' . $default_curr . ' = pur.Currency_ID, (pur.Purchase_Sub_Total),((pur.Purchase_Sub_Total*pur.current_rate)/' . $exchange_rate . '))) as default_sub_total ,         
                        pur.Currency_ID as currency_id,suppliers.supplier_group_id,suppliers.supplier_class_id from tbl_inventory_purchases pur
             inner join tbl_stock_suppliers suppliers on suppliers.Supplier_ID = pur.Supplier_ID
            where pur.current_year_id= ? and  pur.is_actual = ? ' . $cond, $data_set);
        }
        //die(print_r($query));
        $row = $this->db->assoc($query);
        $total = CommonFunctions::formatNumber($row['local_total']) . ' ' . $local_symbol;
        $total_sub = CommonFunctions::formatNumber($row['local_sub_total']) . ' ' . $local_symbol;
        if (CurrencyFactory::getDefaultCurrency() != smc_session()['local_currency']) {
            $total .= '<br/>' . CommonFunctions::formatNumber($row['default_total']) . ' ' . $default_symbol;
            $total_sub .= '<br/>' . CommonFunctions::formatNumber($row['default_sub_total']) . ' ' . $default_symbol;
        }
        return array('total' => $total, 'sub_total' => $total_sub);
    }

    public function get_totals_invoice_discount() {
        $cond = ' ';
        $current_year = $this->year_id;
        $From_Date = $this->info['Date_From'];
        $To_Date = $this->info['Date_To'];
        //        $data_set = [
        //            &$current_year,
        //            &$this->info['is_actual']
        //        ];
        if (!empty($From_Date) && !empty($To_Date)) {
            $cond .= " AND Invoice_Date between '" . $From_Date . "' and  '" . $To_Date . "' ";
        }
        if (is_numeric($this->info['customer_id']))
            $cond .= ' AND Customer_ID = "' . $this->info['customer_id'] . '" ';
        if (!empty($this->info['branch_id']))
            $cond .= " AND branch_id = '" . $this->info['branch_id'] . "' ";
        if (!empty($this->info['user_id']))
            $cond .= ' AND Logged_ID = "' . $this->info['user_id'] . '"';

        if (empty($this->info['show_all_invoice'])) {
            $cond .= ' and (`total_details_discount` > 0 or `total_invoice_discount` > 0) ';
        }


        $default_curr = CurrencyFactory::getDefaultCurrency();
        $exchange_rate = CurrencyFactory::getLastExRate($default_curr);
        $default_symbol = CurrencyFactory::getCurrencySymbol($default_curr);
        $local_symbol = CurrencyFactory::getLocalCurrencySymbol();
        $query = $this->db->query('select Invoice_Date,
                                          Customer_ID,
                                          branch_id,
                                          Logged_ID,
                                          sum(Invoice_Net_Total*current_rate) as main_total,
                                          sum(total_invoice_discount*current_rate) as invoice_discount_total,
                                          sum(total_details_discount*current_rate) as details_discount_total
                                   from invoice_discount_list 
                                   where   current_year_id = "' . $current_year . '" 
                                   and is_actual = "' . $this->info['is_actual'] . '"
                                   ' . $cond);
        $row = $this->db->assoc($query);
        $total = ['main_total' => CommonFunctions::formatNumber($row['main_total']) . ' ' . $local_symbol,
            'invoice_discount_total' => CommonFunctions::formatNumber($row['invoice_discount_total']) . ' ' . $local_symbol,
            'details_discount_total' => CommonFunctions::formatNumber($row['details_discount_total']) . ' ' . $local_symbol,
            'total_without_discount' => CommonFunctions::formatNumber($row['details_discount_total'] + $row['invoice_discount_total'] + $row['main_total']) . ' ' . $local_symbol
        ];
        return $total;
    }

    public function get_total_invoice_details_vehicle_driver() {
        $cond = '';
        if ($this->info['freq'] == 1) {
            $cond .= '  AND Date = "' . smc_escape($this->info['Date']) . '"';
        } else if ($this->info['freq'] == 2) {
            $cond .= '  AND MONTH(Date) = "' . smc_escape($this->info['Date'][1]) . '" AND YEAR(Date) = "' . smc_escape($this->info['Date'][0]) . '"';
        } else if ($this->info['freq'] == 3) {
            $cond .= '  AND YEAR(Date) = "' . smc_escape($this->info['Date'][0]) . '"';
        }
        if ($this->info['is_actual'] == 0) {
            $cond .= ' and is_actual = 0 ';
        }
        if (!empty($this->info['employee_id'])) {
            $cond .= ' and employee_id = "' . $this->info['employee_id'] . '" ';
        } if (!empty($this->info['vehicle_id'])) {
            $cond .= ' and vehicle_id = "' . $this->info['vehicle_id'] . '" ';
        }
        $query = $this->db->prepare_Stmt('select sum(Product_Total_Price*current_rate) as local_total_price,
                                                sum(Product_Total_Price*second_currency_rate) second_total_price,
                                                sum(commission*current_rate) as local_total_commission,
                                                sum(commission*second_currency_rate) second_total_commission 
                                        from product_mov_invoice where is_committed = 1 
                                        and current_year_id="' . $this->year_id . '" ' . $cond);
        $row = $this->db->assoc($query);
        $total_price = CommonFunctions::formatNumber($row['local_total_price']) . ' ' . smc_session()['local_currency_symbol'];
        // HIDE HIDE yousifhide
        if (smc_session()['default_setting']['activate_second_currency'] == 1)
        $total_price .= '<br/>' . CommonFunctions::formatNumber($row['second_total_price']) . ' ' . smc_session()['second_currency']['symbol'];
        
        $total_commission = CommonFunctions::formatNumber($row['local_total_commission']) . ' ' . smc_session()['local_currency_symbol'];
        // HIDE HIDE yousifhide
        if (smc_session()['default_setting']['activate_second_currency'] == 1)
        $total_commission .= '<br/>' . CommonFunctions::formatNumber($row['second_total_commission']) . ' ' . smc_session()['second_currency']['symbol'];
        return [$total_commission, $total_price];
    }

    public function get_total_sales_invoices($freq, $Date, $is_actual, $customer_id) {
        $cond = '';
        if ($freq == 1) {
            $date = $Date;
            $cond .= ' and Invoice_Date = "' . $date . '" ';
        } else if ($freq == 2) {
            $year = $Date[0];
            $month = $Date[1];
            $cond .= ' and YEAR(Invoice_Date) = "' . $year . '" AND MONTH(Invoice_Date) = "' . $month . '"';
        } else if ($freq == 3) {
            $year = $Date[0];
            $cond .= ' and YEAR(Invoice_Date) = "' . $year . '" ';
        }
        $data_set = [
            &$is_actual
        ];
        if (!empty($customer_id)) {
            $cond .= ' and Customer_ID = "' . $customer_id . '"';
            if (!empty($this->info['customer_branch_id']))
                $cond .= ' and customer_branch_id = "' . $this->info['customer_branch_id'] . '"';
        }
        $query = $this->db->prepare_Stmt('select Invoice_Date as date,current_rate,
            sum(Invoice_Net_Total*current_rate) as net_total,
            sum(Invoice_Net_Total*second_currency_rate) as second_net_total,
            Invoice_Currency as currency_id from tbl_invoices 
            where is_actual = ?  and is_committed = 1' . $cond, $data_set);
        $row = $this->db->assoc($query);
        $data = array('net_total' => 0, 'second_net_total' => 0);
        $data['net_total'] = CommonFunctions::formatNumber($row['net_total']);
        $data['second_net_total'] = CommonFunctions::formatNumber($row['second_net_total']);
        return $data;
    }

    public function get_total_sold_brand_items_totals($with_return, $from_date, $to_date, $users, $is_actual, $brand_id) {
        $cond = ' where current_year_id="' . $this->year_id . '" and u.is_actual = "' . $is_actual . '" ';
        if (!empty($from_date) && !empty($to_date)) {
            $cond .= ' AND u.date_created between "' . $from_date . '" AND  "' . $to_date . '"';
        }
        if (!empty($users)) {
            $cond .= ' AND u.Logged_ID in (' . $users . ')';
        }
        if (!empty($_GET['brand_id'])) {
            $cond .= ' and  ' . ($this->info['is_brand'] ? 'brand_id' : 'Category_ID') . '  in (' . $_GET['brand_id'] . ')';
        }
        $cond .=!$with_return ? ' and u.is_committed = 1 ' : '';
        if (!empty($this->info['branch_id'])) {
            $cond .= ' AND  u.branch_id = "' . $this->info['branch_id'] . '"';
        }
        if (!empty($this->info['sales_man_id'])) {
            $cond .= ' AND  u.Sales_ID = "' . $this->info['sales_man_id'] . '"';
        }
        $cond .= ' GROUP BY ' . ($this->info['is_brand'] ? 'brand_id' : 'Category_ID') . ',Currency_ID ';
        $total = 0;
        $quantity = 0;
        $vat1_total = 0;
        $vat2_total = 0;
        $total_with_vat = 0;
        if ($with_return)
            $query_str = 'select sum(Product_Total_Price * current_rate) as total_price,
                sum(vat_amount * current_rate) as vat1_total,
                sum(vat2_amount * current_rate) as vat2_total,
                sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
                sum(Quantity) as  total_quantity,u.Currency_ID,b.brand_id,b.brand_name,
            category.Cat_Name,p.Category_ID,u.branch_id,u.Sales_ID
            from (select i.date_created,`d`.`Product_ID`,`d`.`Product_Quantity` AS `Quantity`,
            `d`.`Product_Total_Price` AS `Product_Total_Price`,`i`.`Invoice_Date` AS `Date`,
            `i`.`Invoice_Currency` AS `Currency_ID`,i.current_year_id,i.Logged_ID ,
            i.created_logged_id,i.is_actual ,i.current_rate,p1.Category_ID,i.branch_id,i.Sales_ID ,
            d.vat_amount,d.vat2_amount
            from `tbl_invoice_products_details` `d`
            join `tbl_invoices` `i`  on `i`.`Invoice_ID_Auto` = `d`.`Invoice_ID_Auto` 
            inner join tbl_stock_products p1 on d.Product_ID = p1.Product_ID 
            where i.is_committed = 1
            union all
            select i.date_created,d.Product_ID,(d.Return_Product_Quantity *(-1)) as Quantity,
            (d.Return_Product_Total * (-1)) as Product_Total_Price,i.Return_Invoice_Date AS `Date`,
            i.Currency_ID,i.current_year_id,i.Logged_ID,i.created_logged_id,i.Is_Actual as is_actual
            ,i.current_rate,p2.Category_ID,i.branch_id,i.Sales_ID ,(d.vat_amount * (-1)) as vat_amount,(d.vat2_amount * (-1)) as va2_amount
            from tbl_accounting_return_items d
            join tbl_accounting_return_invoices i on d.Return_Invoice_ID = i.Return_Invoice_ID 
            inner join tbl_stock_products p2 on d.Product_ID = p2.Product_ID 
            ) as u 
            join tbl_stock_products p on u.Product_ID = p.Product_ID
            inner join tbl_product_cat category on category.Cat_ID = p.Category_ID
            left join tbl_brand_products b on b.brand_id = p.brand_id   ';
        else {
            $query_str = 'select sum((Product_Total_Price) * current_rate) as total_price,
                sum(vat_amount * current_rate) as vat1_total,
                sum(vat2_amount * current_rate) as vat2_total,
                sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
                sum(Quantity) as total_quantity from product_mov_invoice as u';
        }
        $query = $this->db->query($query_str . $cond);
        while ($row = $this->db->assoc($query)) {
            $total += $row['total_price'];
            $quantity += $row['total_quantity'];
            $vat1_total += $row['vat1_total'];
            $vat2_total += $row['vat2_total'];
            $total_with_vat += $row['total_with_vat'];
        }
        //        $row = $this->db->assoc($query);
        //        if (!empty($row)) {
        //            $total = $row['total_price'];
        //            $quantity = $row['total_quantity'];
        //        }
        return [CommonFunctions::formatNumber($quantity),
            CommonFunctions::formatNumber($total),
            CommonFunctions::formatNumber($vat1_total),
            CommonFunctions::formatNumber($vat2_total),
            CommonFunctions::formatNumber($total_with_vat),
        ];
    }

    public function getTotalSoldBrandItems() {
        $condition = ' where current_year_id="' . $this->year_id . '"';
        if (isset($this->info['From_Date'])) {
            $condition .= ' AND u.date_created between "' . $this->info['From_Date'] . '" AND  "' . $this->info['To_Date'] . '"';
        }
        if (!empty($this->info['users'])) {
            $condition .= ' AND u.Logged_ID in (' . $this->info['users'] . ')';
        }
        if (!empty($this->info['brand_id'])) {
            $condition .= ' AND u.brand_id in (' . $this->info['brand_id'] . ')';
        }
        //        if ($this->info['is_actual'] == 0) {
        $condition .= ' and u.is_actual = 0 ';
        //        }
        $data = array();
        $string_query = '';
        if ($this->info['return'] == 0) {
            $string_query = 'select SUM(Quantity) as total_qty,SUM(Product_Total_Price+vat_amount) as total_price,
         brand_name,Logged_ID,Currency_Symbol,UOM_Name from product_mov_invoice u ';
        } else {
            $string_query = 'select brand_name,u.*,um.UOM_Name, c.Currency_Symbol,
            SUM(Quantity) as total_qty,SUM(Product_Total_Price) as total_price from
            (select i.date_created,`d`.`Product_ID`,`d`.`Product_Quantity` AS `Quantity`,(`d`.`Product_Total_Price`+d.vat_amount) AS `Product_Total_Price`,
            `i`.`Invoice_Date` AS `Date`,`i`.`Invoice_Currency` AS `Currency_ID`,i.current_year_id,i.Logged_ID ,i.created_logged_id,i.is_actual 
            from `tbl_invoice_products_details` `d` join `tbl_invoices` `i` on `i`.`Invoice_ID_Auto` = `d`.`Invoice_ID_Auto` 
            union all
            select i.date_created,d.Product_ID,(d.Return_Product_Quantity *(-1)) as Quantity,
            ((d.Return_Product_Total+d.vat_amount) * (-1)) as Product_Total_Price,i.Return_Invoice_Date AS `Date`,i.Currency_ID,i.current_year_id,
            i.Logged_ID,i.created_logged_id,i.Is_Actual as is_actual from tbl_accounting_return_items d join tbl_accounting_return_invoices i 
            on d.Return_Invoice_ID = i.Return_Invoice_ID) u join tbl_stock_products p on u.Product_ID = p.Product_ID 
            join tbl_common_currency c on c.Currency_ID = u.Currency_ID left join tbl_stock_uom um 
            on um.UOM_ID = p.UOM_ID left join tbl_brand_products b using (brand_id)  ';
        }
        $query = $this->db->query($string_query . $condition . ' GROUP BY brand_id,Currency_ID');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function DeliveryFeesSeacrh($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and (delivery_fees_amount LIKE ? or delivery_fees_view LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        $query = $this->db->prepare_Stmt('SELECT delivery_fees_amount as id , delivery_fees_view as text 
            from tbl_delivery_fees where true ' . $cond . ' order by delivery_fees_amount asc  
                limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $row['text'] = empty($row['text']) ? $row['id'] : $row['text'];
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function submitDelivery() {
        $this->db->query('START TRANSACTION');
        $flag = $this->info['delivery_flag'];
        if ($flag == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_delivery_fees
                                     (`delivery_fees_amount`, `delivery_fees_view`)
                                     VALUES
                                    (?,?)
                                         ', [&$this->info['delivery_fees_amount'], &$this->info['delivery_fees_view']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_delivery_fees
                                                 SET
                                                        `delivery_fees_amount` = ?,
                                                        delivery_fees_view = ?
                                                 WHERE 
                                                        delivery_fees_id = ?
                                         ', [&$this->info['delivery_fees_amount'], &$this->info['delivery_fees_view'], &$this->info['delivery_id']]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function get_sales_invoices_total($options) {
        $cond = ' ';
        if (isset($options['customer_supplier_id']) && $options['customer_supplier_id'] != '') {
            $cond .= ' and Customer_ID = "' . $options['customer_supplier_id'] . '"';
        }
        if (isset($options['pos_customer']) && $options['pos_customer'] != '') {
            $cond .= ' and pos_customer_id = "' . $options['pos_customer'] . '"';
        }
        if (isset($options['invoice_status']) && $options['invoice_status'] !== '') {
            $cond .= ' and Invoice_Status in (' . implode(',', $options['invoice_status']) . ')';
        }
        if (isset($options['is_delivery']) && $options['is_delivery'] !== 'all') {
            $cond .= ' and Is_Delivery = "' . $options['is_delivery'] . '"';
        }
        if (!empty($options['inv_list_nb'])) {
            $cond .= ' and concat(invoice_prefix,Invoice_ID) = "' . $options['inv_list_nb'] . '"';
        }
        if (!empty($options['type']) && $options['type'] == 2) {
            $cond .= ' and posponted_type <> 0 ';
        }
        if (!empty($_GET['is_delivery_list'])) {
            $cond .= ' and Is_Delivery = 1 ';
        }
        if (!empty($_GET['branch_id'])) {
            $cond .= ' and branch_id = "' . $_GET['branch_id'] . '"';
        }
        if (!empty($_GET['delivery_user'])) {
            $cond .= ' and Logged_ID = "' . $_GET['delivery_user'] . '" ';
        }
        $cond .= ' and is_actual = "' . $_GET['is_actual'] . '"';
        if (!$this->permissions->hasPermission('view_all_pos_invoices')) {
            $cond .= ' and Logged_ID = "' . smc_session()['user_logged_id'] . '"';
        }
        if (!empty($options['Date_From']) || !empty($options['Date_To'])) {
            $cond .= ' and Invoice_Date between  "' . $options['Date_From'] . '"  and  "' . $options['Date_To'] . '" ';
        }
        if (!empty($options['posponted_status'])) {
            $cond .= ' and posponted_type = "' . $options['posponted_status'] . '"';
        }
        if (!empty($options['due_date_from']) && !empty($options['due_date_to'])) {
            $cond .= ' and ' . ($options['type'] == 1 ? 'Invoice_Due_Date' : 'Date(postponed_date_time)') . '  between  "' . $options['due_date_from'] . '"  and  "' . $options['due_date_to'] . '"';
        }


        if($this->permissions->hasPermission('Branches')){
            $cond .= !empty($options['search_branch_id_for_invoices']) ? ' and tbl_invoices.branch_id ="' . ($options['search_branch_id_for_invoices']) . '"' : '';
        }else{
            $cond .= ' and tbl_invoices.branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
        }
        
        $cond .= ' AND current_year_id = "' . $this->year_id . '"';

        $Employee_ID  =  smc_session()['user_details']['Employee_ID'];
        if (smc_session()['user_details']['limit_customer_invoice'] == 1) {
                $query = $this->db->query('SELECT
                    SUM(
                        (
                            Invoice_Net_Total + Invoice_Shipping
                        ) * current_rate
                    ) AS net_total,
                    SUM(
                        Invoice_Paid_Amount * current_rate
                    ) AS paid_amount,
                    SUM(
                        Invoice_Shipping * current_rate
                    ) AS fees_amount,
                    SUM(
                        (
                            (
                                Invoice_Net_Total + Invoice_Shipping
                            ) - Invoice_Paid_Amount
                        ) * current_rate
                    ) AS remaining,
                    posponted_type,
                    postponed_date_time
                FROM
                    tbl_invoices,
                    tbl_customers,
                    tbl_salesman_customers
                WHERE
                    tbl_invoices.Customer_ID = tbl_customers.Customer_ID AND tbl_salesman_customers.customer_id = tbl_customers.Customer_ID AND tbl_salesman_customers.employee_id = "' . $Employee_ID . '" and ISNULL(exchange_id)' . $cond);
        } else {

            $query = $this->db->query('select sum((Invoice_Net_Total+Invoice_Shipping)*current_rate) as net_total,
            sum(Invoice_Paid_Amount*current_rate) as paid_amount,
             sum(Invoice_Shipping*current_rate) as fees_amount,
            sum(((Invoice_Net_Total+Invoice_Shipping)-Invoice_Paid_Amount)*current_rate) as remaining,posponted_type,postponed_date_time
            from tbl_invoices where isnull(exchange_id) ' . $cond);
        }

        $row = $this->db->assoc($query);
        return $row;
    }

    public function getQuotationToPrint($id) {
        $data = array();
        $year = SESSION::getCurrentYearID();
        $query_main = $this->db->query('select 
                                            Order_ID_Auto,
                                            Order_ID,

                                            from_place ,
                                            to_place,
                                            driver_id,
                                            
                                            created_logged_id,
                                            po,job_inv,project_code ,project_name_inv,our_ref,supply_date,
                                            Order_Date,
                                            sale_due_date,
                                            discount_amount,
                                            discount_percent,
                                            total_vat,
                                            sub_total,
                                            net_total,
                                            is_sales,
                                            is_quotation,
                                            order_description,
                                            Currency_ID,
                                            Currency_Name,
                                            Currency_Symbol,
                                            Person_Name,
                                            Depot_ID,
                                            Depot_Name,
                                            Supplier_ID,
                                            sale_prefix,Status_ID,
                                            is_actual,
                                            (total_vat*current_rate) as local_vat_amount,
                                           current_rate,date_created  
                                        from purchase_order_list
                                        where Order_ID = "' . smc_escape($id) . '"'
                . ' and current_year_id = "' . $this->year_id . '"');
        $row = $this->db->assoc($query_main);

        $row['driver_name'] = CommonBusiness::getDriverByDriverId($row['driver_id']);

        $net_total = $row['net_total'];
        $local_vat_amount = $row['local_vat_amount'];
        $grand_total = $net_total;
        $order_disc_amount = $row['discount_amount'];

        $row['Employee_Name'] = User::get_username_by_id($row['created_logged_id'] );;

        $row['Order_Date_format'] = !empty(smc_session()['default_setting']['report_format_date']) ? date(smc_session()['default_setting']['report_format_date'], strtotime($row['Order_Date'])) : $row['Order_Date'];
        $row['sale_due_date_format'] = !empty(smc_session()['default_setting']['report_format_date']) ? date(smc_session()['default_setting']['report_format_date'], strtotime($row['sale_due_date'])) : $row['sale_due_date'];
        $row['show_vat_class'] = empty($row['total_vat']) ? 'hidden' : '';
        $row['net_total_before_disc'] = $row['sub_total'] - $order_disc_amount;
        $row['sub_total'] = CommonFunctions::formatNumber($row['sub_total']);

        $product_total_price_without_vat = 0;
        $product_total_price_with_vat = 0;
        $product_total_price_ttc_with_vat = 0;

        $product_total_price_without_vat_before_disc = 0;
        $product_total_price_with_vat_before_disc = 0;//getQuotationToPrint

        $all_product_total_price_before_disc = 0;

        $product_total_price_ttc_with_vat_before_disc = 0;

        $product_total_price_with_vat_pos = 0;
        $product_total_price_ttc_with_vat_before_disc_pos = 0;
        $product_total_price_ttc_with_vat_pos = 0;

        $total_vat_amount_before_disc = 0;

        $inv_disc_percentage = $row['discount_percent'];


        $row['net_total'] = CommonFunctions::formatNumber($row['net_total']);
        $row['total_vat'] = CommonFunctions::formatNumber($row['total_vat']);
        $row['discount_percent'] = CommonFunctions::formatNumber($row['discount_percent']);
        $row['discount_amount'] = CommonFunctions::formatNumber($order_disc_amount);
        $row['local_vat_amount'] = CommonFunctions::formatNumber($local_vat_amount);
        $row['local_net_total'] = CommonFunctions::formatNumber(($net_total * $row['current_rate']));
        $row['order_time'] = date("H:i:s");
        $row['net_total_in_usd'] = CommonFunctions::formatNumber(CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['Currency_ID'], 144, $net_total));
        $row['net_total_in_lb'] = CommonFunctions::formatNumber(CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row['Currency_ID'], 84, $net_total));
        $row['grand_total'] = CommonFunctions::formatNumber($grand_total);
        $row['grand_total_word_ar'] = Forms::num_to_word($grand_total, $row['Currency_ID'], 'ar');
        $row['grand_total_word_en'] = Forms::num_to_word($grand_total, $row['Currency_ID'], 'en');
        $row['total_vat_word_ar'] = Forms::num_to_word($row['total_vat'], $row['Currency_ID'], 'ar');
        $row['total_vat_word_en'] = Forms::num_to_word($row['total_vat'], $row['Currency_ID'], 'en');
        $row['local_vat_word_ar'] = Forms::num_to_word($local_vat_amount, smc_session()['local_currency'], 'ar');
        $row['local_vat_word_en'] = Forms::num_to_word($local_vat_amount, smc_session()['local_currency'], 'en');
        $row['net_total_before_disc'] = CommonFunctions::formatNumber($row['net_total_before_disc']);
        if ($row['is_sales'] == 0) {
            $person = Supplier::getSupplierByID($row['Supplier_ID']);
            $row['title'] = $row['is_quotation'] == 0 ? CommonLanguage::getMessage('purchase_orders') : CommonLanguage::getMessage('purchase_quotation');
        } else {
            $person = Customer::getCustomerByID($row['Supplier_ID']);
            $row['title'] = $row['is_quotation'] == 0 ? CommonLanguage::getMessage('sales_order') : CommonLanguage::getMessage('sales_quotation');
        }
        $data['Main'] = array_merge($row, $person);
        $query_details = $this->db->query('select
                                                p.Order_ID,p.Order_ID_Auto AS Order_ID_Auto,
                                                i.Entry_ID,

                                                i.from_time,
                                                i.to_time,
                                                i.modify_date,
                                                 driver.driver_name as driver_name_item,

                                                i.Item_Quantity_Current AS Item_Quantity_Current,
                                                ps.Product_Code AS Code,
                                                ps.Product_Name AS Product_Name,
                                                ps.Product_Limit_Discount,

                                                ps.vat_percent as vat_percent,

                                                i.Item_ID AS Product_ID,
                                                i.vat_percent,
                                                i.vat_amount,
                                                i.note,
                                                uc.Bar_Code,
                                                (i.total_price+i.vat_amount) as Product_Total_Price_TTC,
                                                 i.discount_amount AS product_discount_amount,
                                                i.discount_percent AS product_discount_percent,
                                                i.Unit_Price AS Product_Net_Price,
                                                i.total_price AS Product_Total_Price,
                                                 i.UOM_ID,u.UOM_Name,ps.brand_id,b.brand_name
                                            from 
                                                tbl_purchase_order_details i 
                                            inner join 
                                                tbl_purchase_order p 
                                            on
                                                p.Order_ID = i.Order_ID

                                            left join 
                                                tbl_drivers driver 
                                            on
                                                driver.driver_id = i.driver_id


                                            inner JOIN
                                                uom_conversions uc
                                            ON 
                                                uc.Product_ID = i.Item_ID and uc.uom_from = i.UOM_ID
                                            inner join 
                                                tbl_stock_products ps 
                                            on
                                                ps.Product_ID = i.Item_ID
                                               inner join tbl_stock_uom u on u.UOM_ID = i.UOM_ID
                                               left join tbl_brand_products b on b.brand_id = ps.brand_id
                                            where
                                                p.current_year_id = "' . $year . '"
                                            and 
                                                p.Order_ID = "' . $id . '"
                                            ORDER BY  i.Entry_ID
                                            ');
        $i = 0;
        $tmp_items_arr = array();
        $item_ids_arr = array();
        $entry_ids_arr = array();
        while ($row = $this->db->assoc($query_details)) {
            $tmp_items_arr[$row['Entry_ID']] = $row;
            $entry_ids_arr[] = $row['Entry_ID'];
            $item_ids_arr[$row['Product_ID']] = $row['Product_ID'];
        }
        //echo"<pre>";print_r($tmp_items_arr);exit;
        //
        $data['Main']['invoice_total_quantity'] = 0;
        $inv_ttl_row_disc = 0;    //total discount for all rows
        foreach ($tmp_items_arr as $item_row) {
            $data['Main']['invoice_total_quantity'] += $item_row['Item_Quantity_Current'];
            $inv_ttl_row_disc += $item_row['product_discount_amount'];
            $total_price = $item_row['Product_Total_Price'];
            $vat_amount = $item_row['vat_amount'];

            $item_row['Product_ttc_price'] = $item_row['Product_Net_Price'] + (($item_row['Product_Net_Price'] *  $item_row['vat_percent'])/100);
            $item_row['Product_ttc_price'] = CommonFunctions::formatNumber($item_row['Product_ttc_price']);
            $item_row['Product_vat'] =  (($item_row['Product_Net_Price'] *  $item_row['vat_percent'])/100);
            $item_row['Product_vat'] =  CommonFunctions::formatNumber($item_row['Product_vat']);


            $item_row['Product_Total_Price_Before_Disc'] = $item_row['Product_Net_Price'] * $item_row['Item_Quantity_Current'];
            //Invoice_Discount Product_Discount
            $total_product_no_vat_no_disc = $item_row['Product_Net_Price'] * $item_row['Item_Quantity_Current'];
            $vat_amount_before_disc = ($total_product_no_vat_no_disc * $item_row['vat_percent']) / 100;
            $total_vat_amount_before_disc += ($total_product_no_vat_no_disc * $item_row['vat_percent']) / 100;

            if ($vat_amount > 0 ) {
                $product_total_price_with_vat +=  $total_price;
                $product_total_price_ttc_with_vat = $product_total_price_ttc_with_vat + ($total_price + $vat_amount );
            } else {
                $product_total_price_without_vat +=  $total_price;
            }

            if ($vat_amount > 0 ) {
                $product_total_price_with_vat_before_disc +=  $item_row['Product_Total_Price_Before_Disc'];
                $product_total_price_ttc_with_vat_before_disc = $product_total_price_ttc_with_vat_before_disc + ($item_row['Product_Total_Price_Before_Disc'] + $vat_amount_before_disc );
            } else {
                $product_total_price_without_vat_before_disc +=  $item_row['Product_Total_Price_Before_Disc'];
            }

            if ($vat_amount > 0 ) {

                $disc_amount_product = $total_product_no_vat_no_disc - (($total_product_no_vat_no_disc * $item_row['product_discount_percent']) / 100);
                $disc_amount_product = $disc_amount_product - (($disc_amount_product *  $inv_disc_percentage) / 100);

                $product_total_price_with_vat_pos +=  $disc_amount_product;
                $product_total_price_ttc_with_vat_before_disc_pos = $product_total_price_ttc_with_vat_before_disc_pos + ($total_product_no_vat_no_disc + $vat_amount_before_disc );
                $product_total_price_ttc_with_vat_pos =  $product_total_price_ttc_with_vat_pos + ($total_price + $vat_amount );
            } else {
                $total_product_no_vat_no_disc = $total_product_no_vat_no_disc - (($total_product_no_vat_no_disc * $item_row['product_discount_percent']) / 100);
            }

            $item_row['Product_Net_Price'] = CommonFunctions::formatNumber($item_row['Product_Net_Price']);
            $item_row['product_discount_amount'] = CommonFunctions::formatNumber($item_row['product_discount_amount']);
            $item_row['Product_Total_Price'] = CommonFunctions::formatNumber($item_row['Product_Total_Price']);
            $item_row['Product_Total_Price_TTC'] = CommonFunctions::formatNumber($item_row['Product_Total_Price_TTC']);
            $item_row['vat_amount'] = CommonFunctions::formatNumber($item_row['vat_amount']);
            $item_row['Item_Quantity_Current'] = CommonFunctions::formatNumber($item_row['Item_Quantity_Current'], 2);
            $item_row['Count'] = ++$i;
            $item_row['total_with_vat'] = CommonFunctions::formatNumber(($total_price + $vat_amount));



            $data['Details'][] = $item_row;
        }
        $all_product_total_price_before_disc = $product_total_price_with_vat_before_disc + $product_total_price_without_vat_before_disc;

        $data['Main']['product_total_price_without_vat'] = CommonFunctions::formatNumber($product_total_price_without_vat);
        $data['Main']['product_total_price_with_vat'] = CommonFunctions::formatNumber($product_total_price_with_vat);
        $data['Main']['product_total_price_ttc_with_vat'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat);
        
        $data['Main']['product_total_price_without_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_without_vat_before_disc);
        $data['Main']['product_total_price_with_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_with_vat_before_disc);
        
        $data['Main']['all_product_total_price_before_disc'] = CommonFunctions::formatNumber($all_product_total_price_before_disc);

        $data['Main']['product_total_price_ttc_with_vat_before_disc'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat_before_disc);
        
        $data['Main']['product_total_price_with_vat_pos'] = CommonFunctions::formatNumber($product_total_price_with_vat_pos);
        $data['Main']['product_total_price_ttc_with_vat_pos'] = CommonFunctions::formatNumber($product_total_price_with_vat);
        $data['Main']['product_total_price_ttc_with_vat_before_disc_pos'] = CommonFunctions::formatNumber($product_total_price_ttc_with_vat_before_disc_pos);
        $data['Main']['total_vat_amount_before_disc'] = CommonFunctions::formatNumber($total_vat_amount_before_disc);

        $data['Main']['invoice_total_quantity'] = CommonFunctions::formatNumber($data['Main']['invoice_total_quantity'], 2);
        $data['Main']['invoice_total_row_discount'] = CommonFunctions::formatNumber($inv_ttl_row_disc, 2);
        $data['Main']['invoice_total_full_discount'] = CommonFunctions::formatNumber($order_disc_amount + $inv_ttl_row_disc, 2);    //total discount for both at whole invoice and at invoice rows
        //die("<pre>" . print_r($data, true));
        return $data;
    }

    public function change_invoice_actual($id_arr, $is_actual) {
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        foreach ($id_arr as $id) {
            $query = $this->db->query('select invoice_prefix from tbl_invoices where Invoice_ID_Auto = "' . $id . '"');
            $prefix = $this->db->assoc($query)['invoice_prefix'];
            $inv_nb = self::getMaxInvoice($prefix, $is_actual);
            $this->db->prepare_Stmt('update tbl_invoices set Invoice_ID = ?,is_actual=?,is_main_transfer=0
            where Invoice_ID_Auto = ?', [&$inv_nb, &$is_actual, &$id]);
            $jv = JV::returnJV($is_actual);
            $ref = "Inv." . $prefix . $inv_nb;
            $this->db->prepare_Stmt('update tbl_accounting_transactions set main_nb= ?, 
            is_actual = ?,JV_ID = ?
            where main_id = ? and main_type="inv"', [&$inv_nb, &$is_actual, &$jv, &$id]);
            $this->db->prepare_Stmt('update tbl_accounting_transactions set Transaction_Reference = ?
            where main_id = ? and main_type="inv" and subtype=""', [&$ref, &$id]);
            $this->db->prepare_Stmt('update tbl_stock_product_transactions set is_actual = ?
            where main_id = ? and Transaction_Type_ID in (2,11) ', [&$is_actual, &$id]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function get_total_inv_dist_by_customer() {
        $data = array('invoice_total' => 0, 'invoice_count' => 0);
        $cond = ' and Invoice_Date <= "' . $this->info['To_Date'] . '" and Invoice_Date >= "' . $this->info['From_Date'] . '" and is_committed = 1 ';
        if (isset($this->info['customer']) && $this->info['customer'] != '') {
            $cond .= ' and Customer_ID = "' . $this->info['customer'] . '"';
            if (!empty($this->info['customer_branch_id']))
                $cond .= ' and customer_branch_id = "' . $this->info['customer_branch_id'] . '"';
        }
        if ($this->info['is_actual'] == 0) {
            $cond .= ' and is_actual = 0';
        }
        if (!empty($this->info['sales_man_id'])) {
            $cond .= ' and Sales_ID = "' . $this->info['sales_man_id'] . '"';
        }
        if (!empty($this->info['group_id'])) {
            $cond .= ' and customer_group_id = "' . $this->info['group_id'] . '"';
        }
        if (!empty($this->info['class_id'])) {
            $cond .= ' and customer_class_id = "' . $this->info['class_id'] . '"';
        }
        $query = $this->db->query('
                                   select  sum(invoice_total) as invoice_total,
                                           count(Invoice_ID) as invoice_count
                                   from customer_invoice_distribution
                                   where 1=1 
        ' . $cond);
        $row = $this->db->assoc($query);
        $data['invoice_count'] = $row['invoice_count'];
        $data['invoice_total'] = smc_session()['local_currency_symbol'] . ' ' . CommonFunctions::formatNumber($row['invoice_total']);
        return $data;
    }

    public function generate_ship_trans($inv_id, $status_id) {
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $inv_query = $this->db->query("SELECT i.*,c.Customer_Name,cu.Currency_Symbol FROM tbl_invoices i 
                join tbl_customers c on c.Customer_ID = i.Customer_ID 
                join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency
                WHERE Invoice_ID_Auto='" . $inv_id . "' ");
        $inv_row = $this->db->assoc($inv_query);
        if ($inv_row['shipping_status_id'] == $status_id)
            return;
        if ($inv_row['trans_on_change_status'] == 0 || $inv_row['is_invoice_total_on_shipping'] == 1)
            return;
        //
        $is_picked = 0;
        $picked_query = $this->db->query("SELECT * FROM tbl_accounting_transactions 
            WHERE main_id='" . $inv_id . "' AND main_type= 'inv' and subtype='shps' ");
        if ($this->db->rowsno($picked_query) > 0)
            $is_picked = 1;
        $jv_query = $this->db->query("SELECT DISTINCT JV_ID FROM tbl_accounting_transactions  WHERE main_id='" . $inv_id . "' AND main_type= 'inv' ");
        $jv_assoc = $this->db->assoc($jv_query);
        if (!empty($jv_assoc))
            $jv = $jv_assoc['JV_ID'];
        else
            $jv = JV::returnJV($inv_row['is_actual']);
        //
        $query_ship = $this->db->query('select * from tbl_shipping_company where shipping_company_id = "' . $inv_row['shipping_company_id'] . '"');
        $ship_row = $this->db->assoc($query_ship);
        $ref_num = 'Inv.' . $inv_row['Invoice_ID'];
        $today = date("Y-m-d");
        $logged_id = $inv_row['Logged_ID'];
        $desc = !empty($inv_row['Invoice_Description']) ? $inv_row['Invoice_Description'] : ($inv_row['Customer_Name'] . ' bought products with ' . round(($inv_row['Invoice_Net_Total'] + $inv_row['Invoice_Shipping']), 2) . ' ' . $inv_row['Currency_Symbol']);
        $date_time = date('Y-m-d H:i:s');
        if ($status_id == 3 || ($is_picked == 0 && $status_id == 6)) {
            $data_trans = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $ship_row['main_account_id'],
                "Transaction_Type" => 'Credit',
                "Transaction_Amount" => $inv_row['Invoice_Shipping'],
                "Transaction_Date" => $today,
                "Currency_ID" => $inv_row['Invoice_Currency'],
                "Logged_ID" => $logged_id,
                "created_logged_id" => $logged_id,
                "Transaction_Description" => $desc,
                "date_created" => $date_time,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $inv_row['current_rate'],
                "second_currency_rate" => $inv_row['second_currency_rate'],
                "main_id" => $inv_id,
                "main_type" => "inv",
                "branch_id" => $inv_row['branch_id'],
                "due_date" => $inv_row['Invoice_Due_Date'],
                "main_nb" => $inv_row['Invoice_ID'],
                "prefix" => $inv_row['invoice_prefix'],
                "user_ref" => '',
                "job_id" => $inv_row['job_id'],
                "project_id" => $inv_row['project_id'],
                "salesman_id" => $inv_row['Sales_ID'],
                "subtype" => "shps",
                "current_year_id" => $inv_row['current_year_id']
            ];
            JV::addTransaction($data_trans, $inv_row['is_actual']);
            $data_trans = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $ship_row['shipping_account_id'],
                "Transaction_Type" => 'Debit',
                "Transaction_Amount" => $inv_row['Invoice_Shipping'],
                "Transaction_Date" => $today,
                "Currency_ID" => $inv_row['Invoice_Currency'],
                "Logged_ID" => $logged_id,
                "created_logged_id" => $logged_id,
                "Transaction_Description" => $desc,
                "date_created" => $date_time,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $inv_row['current_rate'],
                "second_currency_rate" => $inv_row['second_currency_rate'],
                "main_id" => $inv_id,
                "main_type" => "inv",
                "branch_id" => $inv_row['branch_id'],
                "due_date" => $inv_row['Invoice_Due_Date'],
                "main_nb" => $inv_row['Invoice_ID'],
                "prefix" => $inv_row['invoice_prefix'],
                "user_ref" => '',
                "job_id" => $inv_row['job_id'],
                "project_id" => $inv_row['project_id'],
                "salesman_id" => $inv_row['Sales_ID'],
                "subtype" => "shps",
                "current_year_id" => $inv_row['current_year_id']
            ];
            JV::addTransaction($data_trans, $inv_row['is_actual']);
        }
        if ($status_id == 6) {
            $customer_acc = Customer::getCustomerAccount($inv_row['Customer_ID'])['Account_ID'];
            $data_trans = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $ship_row['main_account_id'],
                "Transaction_Type" => 'Debit',
                "Transaction_Amount" => ($inv_row['Invoice_Shipping'] + $inv_row['Invoice_Net_Total']),
                "Transaction_Date" => $today,
                "Currency_ID" => $inv_row['Invoice_Currency'],
                "Logged_ID" => $logged_id,
                "created_logged_id" => $logged_id,
                "Transaction_Description" => $desc,
                "date_created" => $date_time,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $inv_row['current_rate'],
                "second_currency_rate" => $inv_row['second_currency_rate'],
                "main_id" => $inv_id,
                "main_type" => "inv",
                "branch_id" => $inv_row['branch_id'],
                "due_date" => $inv_row['Invoice_Due_Date'],
                "main_nb" => $inv_row['Invoice_ID'],
                "prefix" => $inv_row['invoice_prefix'],
                "user_ref" => '',
                "job_id" => $inv_row['job_id'],
                "project_id" => $inv_row['project_id'],
                "salesman_id" => $inv_row['Sales_ID'],
                "subtype" => "shps",
                "current_year_id" => $inv_row['current_year_id']
            ];
            JV::addTransaction($data_trans, $inv_row['is_actual']);
            $data_trans = ["JV_ID" => $jv,
                "Transaction_Reference" => $ref_num,
                "Transaction_Account" => $customer_acc,
                "Transaction_Type" => 'Credit',
                "Transaction_Amount" => ($inv_row['Invoice_Shipping'] + $inv_row['Invoice_Net_Total']),
                "Transaction_Date" => $today,
                "Currency_ID" => $inv_row['Invoice_Currency'],
                "Logged_ID" => $logged_id,
                "created_logged_id" => $logged_id,
                "Transaction_Description" => $desc,
                "date_created" => $date_time,
                "date_time" => $date_time,
                "Current_Ex_Rate" => $inv_row['current_rate'],
                "second_currency_rate" => $inv_row['second_currency_rate'],
                "main_id" => $inv_id,
                "main_type" => "inv",
                "branch_id" => $inv_row['branch_id'],
                "due_date" => $inv_row['Invoice_Due_Date'],
                "main_nb" => $inv_row['Invoice_ID'],
                "prefix" => $inv_row['invoice_prefix'],
                "user_ref" => '',
                "job_id" => $inv_row['job_id'],
                "project_id" => $inv_row['project_id'],
                "salesman_id" => $inv_row['Sales_ID'],
                "subtype" => "shps",
                "current_year_id" => $inv_row['current_year_id']
            ];
            JV::addTransaction($data_trans, $inv_row['is_actual']);
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function correct_ship_trans() {
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $inv_query = $this->db->query("SELECT i.*,c.Customer_Name,cu.Currency_Symbol,
                s.pick_up_date,s.drop_off_date FROM tbl_invoices i 
                join tbl_customers c on c.Customer_ID = i.Customer_ID 
                join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency
                join tbl_invoice_shipping s on s.Invoice_ID_Auto = i.Invoice_ID_Auto
                WHERE i.trans_on_change_status=1 and i.shipping_status_id in (3,6) ");
        while ($inv_row = $this->db->assoc($inv_query)) {
            $inv_id = $inv_row['Invoice_ID_Auto'];
            $status_id = $inv_row['shipping_status_id'];
            $is_picked = 0;
            $picked_query = $this->db->query("SELECT * FROM tbl_accounting_transactions 
            WHERE main_id='" . $inv_id . "' AND main_type= 'inv' and subtype='shps' ");
            $count_trans = $this->db->rowsno($picked_query);
            if ($count_trans > 2)
                continue;
            $is_picked = $count_trans > 0 ? 1 : 0;
            $jv_query = $this->db->query("SELECT DISTINCT JV_ID FROM tbl_accounting_transactions  WHERE main_id='" . $inv_id . "' AND main_type= 'inv' ");
            $jv_assoc = $this->db->assoc($jv_query);
            if (!empty($jv_assoc))
                $jv = $jv_assoc['JV_ID'];
            else
                $jv = JV::returnJV($inv_row['is_actual']);
            //
            $query_ship = $this->db->query('select * from tbl_shipping_company where shipping_company_id = "' . $inv_row['shipping_company_id'] . '"');
            $ship_row = $this->db->assoc($query_ship);
            $ref_num = 'Inv.' . $inv_row['Invoice_ID'];
            $logged_id = smc_session()['user_logged_id'];
            $desc = !empty($inv_row['Invoice_Description']) ? $inv_row['Invoice_Description'] : ($inv_row['Customer_Name'] . ' bought products with ' . round(($inv_row['Invoice_Net_Total'] + $inv_row['Invoice_Shipping']), 2) . ' ' . $inv_row['Currency_Symbol']);
            $date_time = date('Y-m-d H:i:s');
            if ($status_id == 3 || ($is_picked == 0 && $status_id == 6)) {
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $ship_row['main_account_id'],
                    "Transaction_Type" => 'Credit',
                    "Transaction_Amount" => $inv_row['Invoice_Shipping'],
                    "Transaction_Date" => $inv_row['pick_up_date'],
                    "Currency_ID" => $inv_row['Invoice_Currency'],
                    "Logged_ID" => $logged_id,
                    "created_logged_id" => $logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $date_time,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $inv_row['current_rate'],
                    "second_currency_rate" => $inv_row['second_currency_rate'],
                    "main_id" => $inv_id,
                    "main_type" => "inv",
                    "branch_id" => $inv_row['branch_id'],
                    "due_date" => $inv_row['Invoice_Due_Date'],
                    "main_nb" => $inv_row['Invoice_ID'],
                    "prefix" => $inv_row['invoice_prefix'],
                    "user_ref" => '',
                    "job_id" => $inv_row['job_id'],
                    "project_id" => $inv_row['project_id'],
                    "salesman_id" => $inv_row['Sales_ID'],
                    "subtype" => "shps",
                    "current_year_id" => $inv_row['current_year_id']
                ];
                JV::addTransaction($data_trans, $inv_row['is_actual']);
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $ship_row['shipping_account_id'],
                    "Transaction_Type" => 'Debit',
                    "Transaction_Amount" => $inv_row['Invoice_Shipping'],
                    "Transaction_Date" => $inv_row['pick_up_date'],
                    "Currency_ID" => $inv_row['Invoice_Currency'],
                    "Logged_ID" => $logged_id,
                    "created_logged_id" => $logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $date_time,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $inv_row['current_rate'],
                    "second_currency_rate" => $inv_row['second_currency_rate'],
                    "main_id" => $inv_id,
                    "main_type" => "inv",
                    "branch_id" => $inv_row['branch_id'],
                    "due_date" => $inv_row['Invoice_Due_Date'],
                    "main_nb" => $inv_row['Invoice_ID'],
                    "prefix" => $inv_row['invoice_prefix'],
                    "user_ref" => '',
                    "job_id" => $inv_row['job_id'],
                    "project_id" => $inv_row['project_id'],
                    "salesman_id" => $inv_row['Sales_ID'],
                    "subtype" => "shps",
                    "current_year_id" => $inv_row['current_year_id']
                ];
                JV::addTransaction($data_trans, $inv_row['is_actual']);
            }
            if ($status_id == 6) {
                $customer_acc = Customer::getCustomerAccount($inv_row['Customer_ID'])['Account_ID'];
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $ship_row['main_account_id'],
                    "Transaction_Type" => 'Debit',
                    "Transaction_Amount" => ($inv_row['Invoice_Shipping'] + $inv_row['Invoice_Net_Total']),
                    "Transaction_Date" => $inv_row['drop_off_date'],
                    "Currency_ID" => $inv_row['Invoice_Currency'],
                    "Logged_ID" => $logged_id,
                    "created_logged_id" => $logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $date_time,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $inv_row['current_rate'],
                    "second_currency_rate" => $inv_row['second_currency_rate'],
                    "main_id" => $inv_id,
                    "main_type" => "inv",
                    "branch_id" => $inv_row['branch_id'],
                    "due_date" => $inv_row['Invoice_Due_Date'],
                    "main_nb" => $inv_row['Invoice_ID'],
                    "prefix" => $inv_row['invoice_prefix'],
                    "user_ref" => '',
                    "job_id" => $inv_row['job_id'],
                    "project_id" => $inv_row['project_id'],
                    "salesman_id" => $inv_row['Sales_ID'],
                    "subtype" => "shps",
                    "current_year_id" => $inv_row['current_year_id']
                ];
                JV::addTransaction($data_trans, $inv_row['is_actual']);
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customer_acc,
                    "Transaction_Type" => 'Credit',
                    "Transaction_Amount" => ($inv_row['Invoice_Shipping'] + $inv_row['Invoice_Net_Total']),
                    "Transaction_Date" => $inv_row['drop_off_date'],
                    "Currency_ID" => $inv_row['Invoice_Currency'],
                    "Logged_ID" => $logged_id,
                    "created_logged_id" => $logged_id,
                    "Transaction_Description" => $desc,
                    "date_created" => $date_time,
                    "date_time" => $date_time,
                    "Current_Ex_Rate" => $inv_row['current_rate'],
                    "second_currency_rate" => $inv_row['second_currency_rate'],
                    "main_id" => $inv_id,
                    "main_type" => "inv",
                    "branch_id" => $inv_row['branch_id'],
                    "due_date" => $inv_row['Invoice_Due_Date'],
                    "main_nb" => $inv_row['Invoice_ID'],
                    "prefix" => $inv_row['invoice_prefix'],
                    "user_ref" => '',
                    "job_id" => $inv_row['job_id'],
                    "project_id" => $inv_row['project_id'],
                    "salesman_id" => $inv_row['Sales_ID'],
                    "subtype" => "shps",
                    "current_year_id" => $inv_row['current_year_id']
                ];
                JV::addTransaction($data_trans, $inv_row['is_actual']);
            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function submitInvoiceType() {
        $invoice_type_id = $this->info['invoice_type_id'];
        $this->info['account_id'] = empty($this->info['account_id']) ? NULL : $this->info['account_id'];
        $this->info['cash_account_id'] = empty($this->info['cash_account_id']) ? NULL : $this->info['cash_account_id'];
        $this->info['depot_id'] = empty($this->info['depot_id']) ? NULL : $this->info['depot_id'];
        $this->info['customer_id'] = isset($this->info['customer_id']) && $this->info['customer_id'] == '' ? NULL : $this->info['customer_id'];
        $this->info['sort_order'] = empty($this->info['sort_order']) ? NULL : $this->info['sort_order'];
        if ($invoice_type_id == 0) {
            $this->db->prepare_Stmt('INSERT INTO `tbl_invoice_types`(`invoice_type_name`,
                `invoice_type_name_actual`, `account_id`, `sort_order`, `show_on_menu`,cash_account_id,
                depot_id,is_full_paid,depot_options_ids,class_id,class_options_ids,
                customer_id,prevent_change_cust,type,customer_group_id,supplier_group_id,show_fields,
                prevent_change_cash,prevent_change_sales,prevent_change_class,hide_payment,salesman_ids)
                VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [&$this->info['invoice_type_name'],
                &$this->info['invoice_type_name_actual'],
                &$this->info['account_id'], &$this->info['sort_order'], &$this->info['show_on_menu'],
                &$this->info['cash_account_id'], &$this->info['depot_id'], &$this->info['is_full_paid'],
                &$this->info['depot_options_ids'], &$this->info['class_id'], &$this->info['class_options_ids'],
                &$this->info['customer_id'], &$this->info['prevent_change_cust'], $this->info['type'],
                $this->info['customer_group_id'], $this->info['supplier_group_id'], $this->info['show_fields'],
                $this->info['prevent_change_cash'], $this->info['prevent_change_sales'],
                $this->info['prevent_change_class'], $this->info['hide_payment'], $this->info['salesman_ids']]);
        } else {
            $data = [&$this->info['invoice_type_name'], &$this->info['invoice_type_name_actual'], &$this->info['account_id'],
                &$this->info['sort_order'], &$this->info['show_on_menu'], &$this->info['cash_account_id'],
                &$this->info['depot_id'], &$this->info['is_full_paid'],
                &$this->info['depot_options_ids'], &$this->info['class_id'], &$this->info['class_options_ids'],
                &$this->info['customer_id'], &$this->info['prevent_change_cust'], $this->info['type'],
                $this->info['customer_group_id'], $this->info['supplier_group_id'], $this->info['show_fields'],
                $this->info['prevent_change_cash'], $this->info['prevent_change_sales'],
                $this->info['prevent_change_class'], $this->info['hide_payment'], $this->info['salesman_ids'],
                &$invoice_type_id];
//            die(print_r($data));
            $this->db->prepare_Stmt('UPDATE `tbl_invoice_types` set `invoice_type_name` = ?,
                `invoice_type_name_actual` = ?, `account_id` =?, `sort_order` = ?, `show_on_menu` = ?,
                cash_account_id=?,depot_id=?,is_full_paid=?,depot_options_ids=?,class_id=?,class_options_ids=?,
                customer_id=?,prevent_change_cust=?,type=?,customer_group_id=?,supplier_group_id=?,show_fields=?,
                prevent_change_cash=?,prevent_change_sales=?,prevent_change_class=?,hide_payment=?,salesman_ids=?
                where  invoice_type_id = ? ', $data);
        }
        $error = $this->db->error();
        return $error;
    }

    public function deleteInvoiceType($invoice_type_id) {
        $query = $this->db->query('select * from tbl_invoices where  invoice_type_id = "' . $invoice_type_id . '"');
        $row_count = $this->db->rowsno($query);
        if ($row_count > 0) {
            return [CommonLanguage::getMessage('unable_delete_invoice_type')];
        }
        $this->db->prepare_Stmt('Delete from `tbl_invoice_types` WHERE `invoice_type_id` = ?', [&$invoice_type_id]);
        $error = $this->db->error();
        return $error;
    }

    public function getInvoiceTypes($types = '"inv"') {
        $data = array();
        $query = $this->db->query('select * from tbl_invoice_types where show_on_menu =1 and type in (' . $types . ')
            order by sort_order desc');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function get_record_types() {
        $data = array();
        $query = $this->db->query('select * from tbl_invoice_types 
            where show_on_menu =1 
            order by sort_order desc');
        while ($row = $this->db->assoc($query)) {
            $data[$row['type']][] = $row;
        }
        return $data;
    }

    public function get_postponed_orders_total($options) {
        $cond = ' ';
        if (isset($options['customer_supplier_id']) && $options['customer_supplier_id'] != '') {
            $cond .= ' and Supplier_ID = "' . $options['customer_supplier_id'] . '"';
        }
        if (!empty($options['inv_list_nb'])) {
            $cond .= ' and concat(sale_prefix,Order_ID_Auto) = "' . $options['inv_list_nb'] . '"';
        }
        if (!empty($options['branch_id'])) {
            $cond .= ' and branch_id = "' . $options['branch_id'] . '"';
        }
        $cond .= ' and is_actual = "' . $options['is_actual'] . '"';

        if (!empty($options['Date_From']) || !empty($options['Date_To'])) {
            $cond .= ' and Order_Date between  "' . $options['Date_From'] . '"  and  "' . $options['Date_To'] . '" ';
        }
        if (!empty($options['posponted_status'])) {
            $cond .= ' and postponed_status_id = "' . $options['posponted_status'] . '"';
        }
        if (!empty($options['due_date_from']) && !empty($options['due_date_to'])) {
            $cond .= ' and Date(postponed_date_time)  between  "' . $options['due_date_from'] . '"  and  "' . $options['due_date_to'] . '"';
        }
        $cond .= ' AND current_year_id = "' . $this->year_id . '"';
        $query = $this->db->query('select sum((net_total)*current_rate) as net_total
            from tbl_purchase_order where postponed_status_id is not null
            and is_sales = 1 and is_quotation = 0 ' . $cond);
        $row = $this->db->assoc($query);
        return $row;
    }

    public function get_postponed_order_report() {
        $cond = '';
        $data = array();
        if (isset($this->info['customer_id']) && $this->info['customer_id'] != '') {
            $cond .= ' and orders.Supplier_ID = "' . $this->info['customer_id'] . '"';
        }
        if (!empty($this->info['inv_list_nb'])) {
            $cond .= ' and concat_ws("",sale_prefix,Order_ID_Auto) = "' . $this->info['inv_list_nb'] . '"';
        }
        if (!empty($this->info['posponted_status'])) {
            $cond .= ' and orders.postponed_status_id = "' . $this->info['posponted_status'] . '"';
        }
        if (!empty($this->info['branch_id'])) {
            $cond .= ' and orders.branch_id = "' . $this->info['branch_id'] . '" ';
        }
        if (!empty($this->info['category_id'])) {
            $cond .= ' and products.Category_ID in (' . $this->info['category_id'] . ') ';
        }
        if (!empty($this->info['postponed_date_from']) && !empty($this->info['postponed_date_to'])) {
            $cond .= ' and date(orders.postponed_date_time) between  "' . $this->info['postponed_date_from'] . '"  and  "' . $this->info['postponed_date_to'] . '"';
        }
        $cond .= ' and orders.is_actual = "' . $this->info['is_actual'] . '"';
        $orders_query = $this->db->query('select 
                                                 orders.Supplier_ID,
                                                 concat_ws("",sale_prefix,Order_ID_Auto) as ID,
                                                 customers.Customer_Name AS Name,
                                                 orders.postponed_date_time,
                                                 orders.postponed_status_id,
                                                 category.Cat_Name,
                                                 products.Product_Name,
                                                 products.Category_ID,
                                                 details.Item_Quantity_Current,
                                                 details.Entry_ID
                                          from tbl_purchase_order orders
                                          inner join tbl_purchase_order_details details using(Order_ID)
                                          inner join tbl_stock_products products on products.Product_ID = details.Item_ID
                                          inner join tbl_product_cat category on category.Cat_ID = products.Category_ID
                                          inner join tbl_customers customers on customers.Customer_ID = orders.Supplier_ID
                                          where orders.current_year_id = "' . $this->year_id . '" 
                                          and  orders.postponed_status_id is not null
                                          and is_sales = 1 and is_quotation = 0
                                          ' . $cond . '
                                           group by  details.Entry_ID');
        $cat_detail_arr = array();
        $entry_ids = '';
        while ($row = $this->db->assoc($orders_query)) {
            $data[$row['Category_ID']]['category_id'] = $row['Category_ID'];
            $data[$row['Category_ID']]['category_name'] = $row['Cat_Name'];
            $cat_detail_arr[$row['Entry_ID']] = $row['Category_ID'];
            $entry_ids .= (empty($entry_ids) ? '' : ',') . $row['Entry_ID'];
            $data[$row['Category_ID']]['details'][$row['Entry_ID']] = ['invoice_nb' => $row['ID'],
                'customer_name' => $row['Name'],
                'postponed_date_time' => $row['postponed_date_time'],
                'product_name' => $row['Product_Name'],
                'quantity' => $row['Item_Quantity_Current'],
                'tag' => '',
                'criteria_note' => '',
                'criteria_name' => ''];
        }
        if (!empty($entry_ids)) {
            $query = $this->db->query('select criteria.Entry_ID,
                    criteria_main.criteria_name,criteria.criteria_note,
                    group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG
             from tbl_order_product_criteria criteria 
             left join tbl_product_criteria_detail crit_detail on crit_detail.criteria_detail_id=criteria.criteria_detail_id
             left join tbl_product_criteria criteria_main on criteria_main.criteria_id = crit_detail.criteria_id
             where  criteria.Entry_ID in (' . $entry_ids . ')
              group by criteria.Entry_ID,crit_detail.criteria_id');
            while ($row = $this->db->assoc($query)) {
                $tag = $data[$cat_detail_arr[$row['Entry_ID']]]['details'][$row['Entry_ID']]['tag'];
                $data[$cat_detail_arr[$row['Entry_ID']]]['details'][$row['Entry_ID']]['tag'] .= (empty($tag) ? '' : '<br>') . ($row['criteria_name'] . ': ' . $row['TAG']);
                $data[$cat_detail_arr[$row['Entry_ID']]]['details'][$row['Entry_ID']]['criteria_note'] = $row['criteria_note'];
                $data[$cat_detail_arr[$row['Entry_ID']]]['details'][$row['Entry_ID']]['criteria_name'] = $row['criteria_name'];
            }
        }
        return $data;
    }

    public function update_order_postpone_status($id, $status) {
        $mydate = date("Y-m-d H:i:s");
        $logged_id = Session::getUserID();
        $data = [&$this->info['status'], &$mydate, &$logged_id, &$this->info['postponed_note'], &$id];
        $this->db->query('update tbl_purchase_order set postponed_status_id = ?,date_time=?,Logged_ID = ?,
                                postponed_note =?
                        where Order_ID = ?', $data);
        $error = $this->db->error();
        return $error;
    }

    public function deleteDelivery($delivery_id) {
        $this->db->prepare_Stmt('delete from tbl_delivery_fees where delivery_fees_id = ?', [$delivery_id]);
        $error = $this->db->error();
        return $error;
    }

    public function inv_pur_due_date_totals() {
        $data = array();
        $cond = '';
        if (isset($this->info['FromDate']) && isset($this->info['ToDate'])) {
            $cond .= ' and Due_Date between "' . $this->info['FromDate'] . '" AND  "' . $this->info['ToDate'] . '"';
        }
        if (empty($this->info['IsVendor']) && !empty($this->info['customer_group_id']))
            $cond .= ' and customer_group_id ="' . $this->info['customer_group_id'] . '"';
        if (!empty($this->info['person_id']))
            $cond .= ' and Person_ID ="' . $this->info['person_id'] . '" ';
        if (empty($this->info['IsVendor']) && !empty($this->info['salesman_id']))
            $cond .= ' and Sales_ID ="' . $this->info['salesman_id'] . '" ';
        if ($this->info['IsVendor'] == 0)
            $cond .= ' and is_committed = 1';
        $rate_col = 'current_rate';
        if (!empty($this->info['currency_id']) && $this->info['currency_id'] == 2) {
            $rate_col = 'second_currency_rate';
        }

        $table = empty($this->info['IsVendor']) ? 'due_date_invoices' : 'due_date_purchase';
        $query = $this->db->query('select sum(Total*' . $rate_col . ') as total,
            sum(Paid_Amount*' . $rate_col . ') as total_paid,
            sum(net_return*' . $rate_col . ') as total_return,
            sum(remaining_amount*' . $rate_col . ') as total_remaining from ' . $table . ' where 1=1 ' . $cond);
        $row = $this->db->assoc($query);
        if (!empty($row))
            $data = $row;
        return $data;
    }

    public function customer_daily_report() {
        $data = array();
        $cust_arr = array();
        $cond = '';
        $total_receipt = 0;
        $total_inv = 0;
        $balance = 0;
        if (empty($this->info['is_actual']))
            $cond .= ' and is_actual=0 ';
        if (!empty($this->info['search_branch_id']))
            $cond .= ' and branch_id='.$this->info['search_branch_id'].' ';
        
        
        //        if(!empty($this->info['salesman_id']))
        //            $cond .= ' and ';
        $query = $this->db->query('select Customer_ID,Customer_Name from tbl_customers where 1=1 ' .
                (!empty($this->info['customer_group_id']) ? ' and customer_group_id = "' . $this->info['customer_group_id'] . '" ' : ''));
        while ($row = $this->db->assoc($query)) {
            $cust_arr[$row['Customer_ID']] = array(
                'customer_name' => $row['Customer_Name'],
                'invoices' => 0,
                'receipts' => 0,
                'balance' => 0
            );
        }
        $customers_array = array_keys($cust_arr);
        $query = $this->db->query('select Customer_ID,Invoice_Paid_Amount,
            (Invoice_Net_Total*current_rate) as local_net,(Invoice_Paid_Amount*current_rate) as local_paid 
            from tbl_invoices where Invoice_Date = "' . $this->info['date'] . '" 
            and current_year_id = "' . $this->year_id . '" ' .
                (!empty($this->info['salesman_id']) ? ' and Sales_ID = "' . $this->info['salesman_id'] . '" ' : '') . $cond);
        while ($row = $this->db->assoc($query)) {
            if (in_array($row['Customer_ID'], $customers_array)) {
                $cust_arr[$row['Customer_ID']]['invoices'] += $row['local_net'];
                $cust_arr[$row['Customer_ID']]['receipts'] += $row['local_paid'];
                $cust_arr[$row['Customer_ID']]['balance'] += $row['local_net'];
                $cust_arr[$row['Customer_ID']]['balance'] -= $row['local_paid'];
            }
        }
        //
        $query = $this->db->query('select main_id,(d.payment_amount*d.current_rate) as local_paid
            from tbl_payment_receipt_details d join tbl_payment_receipt p on p.pay_rec_id = d.pay_rec_id
            join tbl_chart_of_accounts a on a.Account_ID = p.Account_ID where main_type="cust" and sub_type="main"
            and payment_date = "' . $this->info['date'] . '" and current_year_id = "' . $this->year_id . '" ' .
                (!empty($this->info['salesman_id']) ? ' and p.salesman_id = "' . $this->info['salesman_id'] . '" ' : '') . $cond);
        while ($row = $this->db->assoc($query)) {
            if (in_array($row['main_id'], $customers_array)) {
                $cust_arr[$row['main_id']]['receipts'] += $row['local_paid'];
                $cust_arr[$row['main_id']]['balance'] -= $row['local_paid'];
            }
        }
        foreach ($cust_arr as $row) {
            if ($row['invoices'] == 0 && $row['receipts'] == 0)
                continue;
            $total_inv += $row['invoices'];
            $total_receipt += $row['receipts'];
            $balance += $row['balance'];

            $row['receipts'] = CommonFunctions::formatNumber($row['receipts']);
            $row['invoices'] = CommonFunctions::formatNumber($row['invoices']);
            $row['balance'] = CommonFunctions::formatNumber($row['balance']);

            $row = array_values($row);
            if ($row[2] == 0)
                $row['class'] = 'red-star';
            $data[] = $row;
        }
        return ['html' => $data,
            'total_inv' => CommonFunctions::formatNumber($total_inv),
            'total_receipt' => CommonFunctions::formatNumber($total_receipt),
            'balance' => CommonFunctions::formatNumber($balance)];
    }

    public function submit_consumption() {
        $error = token_unique::is_valid_token();
        if (!empty($error))
            return $error;
//        if (!empty($this->info['unique_id']) && !empty(smc_session()['default_setting']['is_production'])) {
//            if (!isset(smc_session()['duplicate_check'][$this->info['unique_id']])) {
//                $error = array();
//                $error[0] = CommonLanguage::getMessage('duplicate_record');
//                return $error;
//            } else {
//                unset(smc_session()['duplicate_check'][$this->info['unique_id']]);
//            }
//        }
        $is_actual = isset($this->info['is_actual']) ? $this->info['is_actual'] : 0;
        $check = CommonFunctions::check_lock_data(['type' => 'consumption', 'start_date' => $this->info['consumption_date'], 'is_actual' => $is_actual]);

//        $check = JV::checkCurrentYear($this->info['consumption_date'], $this->info['consumption_date'], $is_actual);
        if ($check !== '') {
            $error = array();
            $error[0] = $check;
            return $error;
        }
        $depot_id = $this->info['Depot_ID'];
        $branch_id = isset($this->info['branch_id']) ? $this->info['branch_id'] : CommonBusiness::getBranchByDepot($depot_id);
        $this->info['branch_id'] = $branch_id;
        if (isset($this->info['consumption_prefix']))//sync from branch to server or from distribution app
            $consumption_prefix = $this->info['invoice_prefix'];
        else {
            //on server and invoice assigned to branch
            if ((smc_session()['default_setting']['sync_type'] == 1 && smc_session()['default_setting']['default_branch_id'] != $branch_id)) {
                $consumption_prefix = '';
            } else {//normal invoice or [sync from server to branch we already unset]
                $query_branch = $this->db->query('select branch_prefix from tbl_organization_branches where branch_id = "' . $branch_id . '"');
                $branch_prefix = $this->db->assoc($query_branch)['branch_prefix'];
                $consumption_prefix = smc_session()['user_accounts']['serial_prefix'] ? smc_session()['user_accounts']['serial_prefix'] : $branch_prefix;
            }
        }
        $consumption_auto_id = $this->info['consumption_auto_id'];
        $mydate = date("Y-m-d H:i:s");
        $logged_id = Session::getUserID();
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $this->info['Customer_ID'] = isset($this->info['Customer_ID']) ? $this->info['Customer_ID'] : NULL;
        $this->info['consumption_description'] = !empty($this->info['consumption_description']) ? $this->info['consumption_description'] : NULL;
        $consumption_trans_type = '';
        $consumption_prefix_num = '';
        if ($consumption_auto_id == 0) {
            $consumption_trans_type = 'add_consumption';
            $consumption_num = self::getMaxConsumption($consumption_prefix, $is_actual);
            $this->db->prepare_Stmt('INSERT INTO `tbl_consumption`
            (`consumption_id`, `consumption_prefix`, `Customer_ID`, `consumption_date`, `date_created`, `Logged_ID`,
            `created_logged_id`, `Sales_ID`, `current_year_id`, `date_time`, `consumption_description`, `depot_id`,
            `branch_id`, `is_actual`)
            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [&$consumption_num, &$consumption_prefix, &$this->info['Customer_ID'],
                &$this->info['consumption_date'], &$mydate, &$logged_id, &$logged_id, &$this->info['Sales_ID'],
                &$this->year_id, &$mydate, &$this->info['consumption_description'],
                &$depot_id, &$branch_id, &$is_actual]);
            $consumption_auto_id = $this->db->id();
            $consumption_prefix_num = $consumption_prefix . $consumption_num;
        } else {
            $consumption_trans_type = 'edit_consumption_new';
            $entry_ids = [];
            $this->db->prepare_Stmt('update `tbl_consumption`
            set   `Customer_ID` = ?, `consumption_date` = ?,  `Logged_ID` = ?,
            `Sales_ID` = ?, `current_year_id` = ?, `date_time` = ?, 
            `consumption_description` = ?, `depot_id` = ?,`branch_id` = ?, `is_actual` = ? where consumption_auto_id = ?', [&$this->info['Customer_ID'],
                &$this->info['consumption_date'], &$logged_id, &$this->info['Sales_ID'],
                &$this->year_id, &$mydate, &$this->info['consumption_description'],
                &$depot_id, &$branch_id, &$is_actual, &$consumption_auto_id]);
            $entry_query = $this->db->query('
            select details.*,
                   details.product_quantity as quantity,
                   details.item_quantity_current as current_quantity,
                   main.Customer_ID,
                   main.date_time,
                   main.is_actual,
                   main.created_logged_id,
                   main.consumption_prefix,
                   main.date_created,
                   main.consumption_prefix,
                   main.consumption_id,
                   products.is_service
            from tbl_consumption_details details 
            inner join tbl_stock_products products on products.Product_ID = details.product_id
            inner join tbl_consumption main using(consumption_auto_id)
            where  consumption_auto_id = "' . $consumption_auto_id . '"');
            while ($row = $this->db->assoc($entry_query)) {
                $entry_ids[] = $row['entry_id'];
                $consumption_num = $row['consumption_prefix'] . $row['consumption_id'];
                $consumption_prefix_num = $row['consumption_prefix'] . $row['consumption_id'];
                $prefix = $row['consumption_prefix'];
                $old_created_logged_id = $row['created_logged_id'];
                $old_date_time = $row['date_time'];
                $old_date_created = $row['date_created'];
                $old_expiry_date = !empty($row['expiry_date']) ? $row['expiry_date'] : null;
                $old_lot_nb = !empty($row['lot_nb']) ? $row['lot_nb'] : '';
                $old_serial_nb = !empty($row['serial_nb']) ? $row['serial_nb'] : '';
                $ProductQuantityRate = $row['quantity'] / $row['current_quantity'];
                $costdata = [
                    "Product_ID" => '', //$row['Product_ID'],
                    "Quantity" => '', //$row['Quantity'],
                    "Unit_Cost" => '',
                    "unit_price" => 0,
                    "Currency_ID" => smc_session()['local_currency'],
                    "date_time" => $row['date_time'],
                    "date_time_now" => $mydate,
                    "current_rate" => 1,
                    "depot_id" => $row['depot_id'],
                    "trans_date" => $this->info['consumption_date'],
                    "current_quantity" => '', //$row['Current_Quantity'],
                    "uom_id" => '', //$row['UOM_ID'],
                    "is_actual" => $row['is_actual'],
                    "expiry_date" => $old_expiry_date,
                    "lot_nb" => $old_lot_nb,
                    "serial_nb" => $old_serial_nb,
                    "main_id" => $consumption_auto_id,
                    "is_service" => $row['is_service'],
                    "main_nb" => $consumption_num,
                    "customer_id" => $row['Customer_ID']
                ];
                $product_links = CommonBusiness::get_product_links($row['product_id'], $row['uom_id'], $row['quantity'], $row['current_quantity'], '-');
                //                               echo"<pre>";die(print_r($product_links));
                foreach ($product_links as $link) {
                    $costdata["Quantity"] = $link['Quantity'];
                    $costdata["current_quantity"] = $link['current_quantity'];
                    $costdata["Product_ID"] = $link['Product_ID'];
                    $costdata["uom_id"] = $link['uom_id'];
                    $costdata['is_inverse'] = $link['is_oprtn_inverse'];

                    $cost = CommonBusiness::viewCurrentProductCost($link['Product_ID']);
                    $costdata['Unit_Cost'] = $cost;
                    // echo $costdata['Unit_Cost'].='==';
                    self::updateLinkQuantities($costdata, "edit_consumption_old", ($link['operation'] == '+' ? '-' : '+'));
                }
            }
            if (!empty($entry_ids))
                $this->db->prepare_Stmt('delete from tbl_consumption_product_criteria where entry_id in (' . implode(',', $entry_ids) . ')');
            $this->db->prepare_Stmt('delete from tbl_consumption_details where consumption_auto_id = ?', [&$consumption_auto_id]);
        }
        CommonBusiness::update_trans_record_current('con', $consumption_auto_id);
        $expiry_valid_arr = array();
        $serial_valid_arr = array();
        $lot_valid_arr = array();
        $qty_valid_arr = array();
        $depot_arr = array();
        foreach ($this->info['Products'] as $item) {
            $ProductID = $item['product_id'];
            $ProductQuantityRate = Product::getConvertedQuantity($item['uom_id'], 1, $item['product_id']);
            $ProductQuantity = $ProductQuantityRate * $item['item_quantity'];
            $Product_Description = isset($item['product_description']) ? $item['product_description'] : '';
            $expiry_date = !empty($item['expiry_date']) ? $item['expiry_date'] : null;
            $depot_detail_id = !empty($item['depot_id']) ? $item['depot_id'] : $depot_id;
            $lot_nb = !empty($item['lot_nb']) ? $item['lot_nb'] : '';
            $serial_nb = !empty($item['serial_nb']) ? $item['serial_nb'] : '';
            $item['is_service'] = !empty($item['is_service']) ? $item['is_service'] : 0;
            if (empty($depot_arr[$depot_detail_id]))
                $depot_arr[$depot_detail_id] = $depot_detail_id;
            $prod = [&$consumption_auto_id, &$ProductID, &$ProductQuantity,
                &$item['item_quantity'], &$item['uom_id'],
                &$Product_Description, &$expiry_date, &$depot_detail_id,
                &$lot_nb, &$serial_nb];
            $this->db->prepare_Stmt("INSERT INTO `tbl_consumption_details`
                ( `consumption_auto_id`, `product_id`, `product_quantity`, `item_quantity_current`, `uom_id`,
                 `product_description`, `expiry_date`, `depot_id`, `lot_nb`, `serial_nb`)
                VALUES (?,?,?,?,?,?,?,?,?,?)", $prod);
            $new_entry_id = $this->db->id();
            if (!empty($item['criteria_details'])) {
                $criteria_details = $item['criteria_details'];
                foreach ($criteria_details as $details) {
                    $details['criteria_note'] = empty($details['criteria_note']) ? '' : $details['criteria_note'];
                    $this->db->prepare_Stmt("INSERT INTO
                                        tbl_consumption_product_criteria 
                                        (entry_id,quantity,criteria_detail_id,criteria_note)
                                        VALUES
                                        (?,?,?,?)
                    ", [&$new_entry_id, &$details['quantity'], &$details['criteria_detail_id'], &$details['criteria_note']]);
                }
            }
            $costdata = [
                "Product_ID" => $ProductID,
                "Quantity" => $ProductQuantity,
                "Unit_Cost" => "",
                "unit_price" => 0,
                "Currency_ID" => smc_session()['local_currency'],
                "date_time" => $mydate,
                "date_time_now" => $mydate,
                "current_rate" => 1,
                "depot_id" => $depot_detail_id,
                "trans_date" => $this->info['consumption_date'],
                "current_quantity" => $item['item_quantity'],
                "uom_id" => $item['uom_id'],
                "is_actual" => $is_actual,
                "expiry_date" => $expiry_date,
                "lot_nb" => $lot_nb,
                "serial_nb" => $serial_nb,
                "main_id" => $consumption_auto_id,
                "is_service" => $item['is_service'],
                "main_nb" => $consumption_prefix_num,
                "customer_id" => $this->info['Customer_ID']
            ];
            $product_links = CommonBusiness::get_product_links($ProductID, $item['uom_id'], $ProductQuantity, $item['item_quantity'], '-');
            foreach ($product_links as $link) {
                $costdata["Quantity"] = $link['Quantity'];
                $costdata["current_quantity"] = $link['current_quantity'];
                $costdata["Product_ID"] = $link['Product_ID'];
                $costdata["uom_id"] = $link['uom_id'];
                $costdata['is_inverse'] = $link['is_oprtn_inverse'];

                self::updateLinkQuantities($costdata, $consumption_trans_type, $link['operation']) * ($link['Quantity'] / ($ProductQuantityRate * $item['item_quantity']));
                if (!empty($expiry_date) && !empty(smc_session()['default_setting']['activate_expiry_qty_exist'])) {
                    $expiry_valid_arr['expiry'][] = $expiry_date;
                    if (!isset($expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date]))
                        $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] = 0;
                    $expiry_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$expiry_date] += $link['Quantity'];
                }
                if (!empty($serial_nb) && !empty(smc_session()['default_setting']['activate_serial_qty_exist'])) {
                    $serial_valid_arr['serial'][] = $serial_nb;
                    if (!isset($serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb]))
                        $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] = 0;
                    $serial_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$serial_nb] += $link['Quantity'];
                }
                if (!empty($lot_nb) && !empty(smc_session()['default_setting']['activate_lot_qty_exist'])) {
                    $lot_valid_arr['lot'][] = $lot_nb;
                    if (!isset($lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb]))
                        $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] = 0;
                    $lot_valid_arr['prod'][$link['Product_ID']][$depot_detail_id][$lot_nb] += $link['Quantity'];
                }
                if (!empty($link['Quantity']) && empty(smc_session()['default_setting']['negative_sales'])) {
                    if (!isset($qty_valid_arr[$link['Product_ID']][$depot_detail_id]))
                        $qty_valid_arr[$link['Product_ID']][$depot_detail_id] = 0;
                    $qty_valid_arr[$link['Product_ID']][$depot_detail_id] += $link['Quantity'];
                }
            }
            if (!empty($expiry_valid_arr)) {
                $expiry_valid = CommonBusiness::validate_expiry_qty_exist($expiry_valid_arr, $depot_arr);
                if (!empty($expiry_valid)) {
                    if (!$this->stop_transaction_start_end)
                        $this->db->query('ROLLBACK');
                    return ['expiry_error', $expiry_valid];
                }
            }
            if (!empty($lot_valid_arr)) {
                $lot_valid = CommonBusiness::validate_lot_qty_exist($lot_valid_arr, $depot_arr);
                if (!empty($lot_valid)) {
                    if (!$this->stop_transaction_start_end)
                        $this->db->query('ROLLBACK');
                    return ['lot_error', $lot_valid];
                }
            }
            if (!empty($serial_valid_arr)) {
                $serial_valid = CommonBusiness::validate_serial_qty_exist($serial_valid_arr, $depot_arr);
                if (!empty($serial_valid)) {
                    if (!$this->stop_transaction_start_end)
                        $this->db->query('ROLLBACK');
                    return ['serial_error', $serial_valid];
                }
            }
            if (!empty($qty_valid_arr)) {
                $qty_valid = CommonBusiness::validate_product_qty_exist($qty_valid_arr, $depot_arr);
                if (!empty($qty_valid)) {
                    if (!$this->stop_transaction_start_end)
                        $this->db->query('ROLLBACK');
                    return ['qty_error', $qty_valid];
                }
            }
        }

        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query("COMMIT");
            token_unique::remove_token();
            return [$consumption_auto_id, ($consumption_prefix . $consumption_num)];
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query("ROLLBACK");
            return array_unique($error);
        }
    }

    public function getMaxConsumption($prefix, $is_actual = 0) {
        $yearid = $is_actual ? $this->year_id_actual : $this->year_id;
        $query = $this->db->query('SELECT MAX(consumption_id) AS Entry_ID 
            FROM tbl_consumption where 1=1 AND current_year_id = "' . $yearid . '" '
                . 'and consumption_prefix = "' . $prefix . '" and is_actual = "' . $is_actual . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $Invoice = $row['Entry_ID'] + 1;
        else
            $Invoice = 1;
        return $Invoice;
    }

    public function getConsumptionByID($id) {
        $start = microtime(true);
        $data = array("Main" => array(), "Details" => array());
        $year = SESSION::getCurrentYearID();
        $entry_ids_array = array();
        $entry_ids_str = '';
        $query_main = $this->db->query('select 
          i.current_year_id,
          concat(i.consumption_prefix,i.consumption_id) AS ID,
          i.consumption_auto_id AS Auto_ID,
          i.consumption_date AS Date,
          i.depot_id,
          i.Customer_ID,
          c.Customer_Name,
          i.consumption_prefix,
          concat(`e`.`Employee_FirstName`," ",`e`.`Employee_LastName`) AS Employee_Name,
          i.Sales_ID,
          i.consumption_description,
          dp.Depot_Name
          from `tbl_consumption` `i`
          join `tbl_customers` `c`  on `i`.`Customer_ID` = `c`.`Customer_ID` 
          left join `tbl_hrm_employee` `e` on `e`.`Employee_ID` = `i`.`Sales_ID` 
          join `tbl_stock_depot_warehouse` `dp` on `dp`.`Depot_ID` = `i`.`Depot_ID`
          where consumption_auto_id = "' . smc_escape($id) . '" and current_year_id = "' . $this->year_id . '"');
        $row = $this->db->assoc($query_main);
        $data['Main'] = $row;
        if (!empty($row)) {
            $data['Person'] = Customer::getCustomerByID($data['Main']['Customer_ID']);

            $data['item_loc'] = array();
            $query_details = $this->db->query('select
                                                i.entry_id,
                                                p.consumption_auto_id,
                                                i.item_quantity_current AS item_quantity_current,
                                                ps.Product_Code AS Code,
                                                ps.Product_Name AS Name,
                                                ps.Product_Limit_Discount,
                                                ps.is_tax,
                                                ps.is_lot,
                                                ps.is_serial,
                                                ps.is_service,
                                                ps.Status_ID,
                                                (( if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity) /uc.conversion_amount)+ i.item_quantity_current) as Product_Quantity,
                                                (( if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)/uc.conversion_amount)+i.item_quantity_current) AS Quantity,
                                                i.product_description,
                                                uc.Bar_Code,
                                                (i.product_quantity/i.item_quantity_current) AS uom_con,
                                                 i.uom_id,
                                                 ps.is_expiry,
                                                 i.expiry_date,
                                                 i.depot_id,
                                                 w.Depot_Code,
                                                 w.Depot_Name,
                                                 ps.Category_ID,
                                                 i.serial_nb,
                                                 i.lot_nb,
                                                 i.product_id,
                                                 i.product_quantity as def_in_qty,
                                                 l.Product_Depot_Quantity as depot_qty
                                            from 
                                                 tbl_consumption_details i 
                                            inner join 
                                                tbl_consumption p 
                                            on
                                                p.consumption_auto_id = i.consumption_auto_id
                                            inner JOIN
                                                uom_conversions uc
                                            ON 
                                                uc.Product_ID = i.product_id
                                            and 
                                                i.UOM_ID = uc.uom_from
                                            inner join 
                                                tbl_stock_products ps 
                                            on
                                                ps.Product_ID = i.product_id
                                            left  join
                                                tbl_stock_product_location l
                                            on 
                                                l.Location_Product_ID = i.product_id 
                                            and 
                                                l.Product_Depot_ID = i.depot_id
                                            inner join tbl_stock_depot_warehouse w on w.Depot_ID = i.depot_id
                                            where
                                                p.current_year_id = "' . $year . '"
                                            and 
                                                p.consumption_auto_id = "' . $id . '"
                                            ');
            $product_entry_ids = array();
            //            $product_ids = array();
            while ($row = $this->db->assoc($query_details)) {
                if (empty($data['item_loc'][$row['product_id']][$row['depot_id']]))
                    $data['item_loc'][$row['product_id']][$row['depot_id']] = 0;
                $data['item_loc'][$row['product_id']][$row['depot_id']] += $row['def_in_qty'];

                $product_entry_ids[$row['product_id']][] = $row['entry_id'];
                $row['Product_UOM'] = '';
                $data['Details'][$row['entry_id']] = $row;
                $entry_ids_array[] = $row['entry_id'];
            }
            if (!empty($entry_ids_array)) {
                //            echo(microtime(true) - $start).'===';
                $uom_products_query = $this->db->query('select uom_from,Product_ID from tbl_uom_conversions where Product_ID IN (' . implode(',', array_keys($product_entry_ids)) . ') ');
                while ($uom_row = $this->db->assoc($uom_products_query)) {
                    foreach ($product_entry_ids[$uom_row['Product_ID']] as $entry_id) {
                        if ($data['Details'][$entry_id]['Product_UOM'] != '')
                            $data['Details'][$entry_id]['Product_UOM'] .= '/';
                        $data['Details'][$entry_id]['Product_UOM'] .= $uom_row['uom_from'];
                    }
                }
            }
            if (!empty($entry_ids_array)) {
                $entry_ids_str = implode(',', $entry_ids_array);
                $criteria_details_query = $this->db->query('select  consumption_criteria.entry_id,
                                                            crit_details.criteria_detail_id,
                                                            crit_details.criteria_detail_name, 
                                                            consumption_criteria.criteria_note,
                                                            crit_details.criteria_id
                                                    from tbl_consumption_product_criteria consumption_criteria
                                                    inner join tbl_product_criteria_detail crit_details
                                                    using(criteria_detail_id)
                                                    where consumption_criteria.entry_id IN (' . $entry_ids_str . ')
                                                    ');
                while ($row = $this->db->assoc($criteria_details_query)) {
                    $data['Details'][$row['entry_id']]['criteria'][] = $row;
                }
            }
        }
        return $data;
    }

    public function get_cust_sold_header($limit) {
        $header_arr = array();
        $header_arr[] = ['name' => CommonLanguage::getMessage('customer_name'), 'colspan' => 1, 'uom' => ''];
        $query = $this->db->query('select concat_ws(" ",Product_Code,Product_Name) as name,
            u.UOM_Name as uom
            from tbl_stock_products p
            join tbl_stock_uom u on u.UOM_ID = p.default_view_uom_id
            order by Product_Code,Product_Name
            limit ' . $limit);
        while ($row = $this->db->assoc($query)) {
            $row['colspan'] = 2;
            $header_arr[] = $row;
        }
        $header_arr['others'] = ['name' => CommonLanguage::getMessage('others'), 'colspan' => 1, 'uom' => ''];
        $header_arr['totals'] = ['name' => CommonLanguage::getMessage('totals'), 'colspan' => 1, 'uom' => ''];
        return $header_arr;
    }

    public function customer_sold_items_report() {
        $data = array();
        $header = array('customer_name' => '');
        $product_arr = array();
        $cond = '';
        if (!empty($this->info['salesman_id']))
            $cond .= ' and i.Sales_ID = "' . $this->info['salesman_id'] . '" ';
        if (!empty($this->info['branch_id']))
            $cond .= ' and i.branch_id = "' . $this->info['branch_id'] . '" ';
        if (empty($this->info['is_actual']))
            $cond .= ' and i.is_actual = 0 ';
        if (!empty($this->info['Date_To']) && !empty($this->info['Date_From']))
            $cond .= ' and i.Invoice_Date between "' . $this->info['Date_From'] . '" and "' . $this->info['Date_To'] . '" ';
        $limit = !empty($this->info['default_visible_product']) ? $this->info['default_visible_product'] : 10;
        $query = $this->db->query('select Product_ID,Product_Code,Product_Name
            from tbl_stock_products order by Product_Code,Product_Name limit ' . $limit);
        while ($row = $this->db->assoc($query)) {
            $product_arr[$row['Product_ID']] = $row;
            $header[$row['Product_ID'] . '_qty'] = 0;
            $header[$row['Product_ID'] . '_price'] = 0;
        }
        //        echo"<pre>";
        //        die(print_r($product_arr));
        //        $header['other_qty'] = 0;
        $header['other_price'] = 0;
        //        $header['total_qty'] = 0;
        $header['total_price'] = 0;
        //
        $query = $this->db->query('select Customer_ID,Customer_Name from tbl_customers where 1=1 ' . (!empty($this->info['customer_group_id']) ? ' and customer_group_id = "' . $this->info['customer_group_id'] . '"' : ''));
        while ($row = $this->db->assoc($query)) {
            foreach (array_keys($header) as $head)
                if ($head == 'customer_name')
                    $data[$row['Customer_ID']][$head] = $row['Customer_Name'];
                else
                    $data[$row['Customer_ID']][$head] = 0;
        }
        //
        $query = $this->db->query('SELECT d.Product_ID,
            sum(d.`Product_Quantity`/p.default_view_rate) as quantity,
            (d.`Product_Total_Price`*i.current_rate) as price,i.Customer_ID
            FROM `tbl_invoice_products_details` d join tbl_invoices i 
            on i.Invoice_ID_Auto = d.`Invoice_ID_Auto`
            join tbl_stock_products p on p.Product_ID = d.Product_ID
            where 1=1 ' . $cond . '
            group by i.Customer_ID,d.Product_ID');
        while ($row = $this->db->assoc($query)) {
            if (array_key_exists($row['Product_ID'], $product_arr)) {
                $data[$row['Customer_ID']][$row['Product_ID'] . '_qty'] = CommonFunctions::formatNumber($row['quantity']);
                $data[$row['Customer_ID']][$row['Product_ID'] . '_price'] = CommonFunctions::formatNumber($row['price']);
            } else {
                //                $data[$row['Customer_ID']]['other_qty']+=$row['quantity'];
                $data[$row['Customer_ID']]['other_price'] += $row['price'];
            }
            //            $data[$row['Customer_ID']]['total_qty']+=$row['quantity'];
            $data[$row['Customer_ID']]['total_price'] += $row['price'];
        }
        $final_data = array();
        foreach ($data as $row) {
            unset($row['Product_ID']);
            unset($row['Customer_ID']);
            //            $row['total_qty'] = CommonFunctions::formatNumber($row['total_qty']);
            if ($row['total_price'] != 0) {
                $row['total_price'] = CommonFunctions::formatNumber($row['total_price']);
                //            $row['other_qty'] = CommonFunctions::formatNumber($row['other_qty']);
                $row['other_price'] = CommonFunctions::formatNumber($row['other_price']);
                $final_data[] = array_values($row);
            }
        }
        return $final_data;
    }

    public function get_invoice_type_by_id($id) {
        $data = array();
        $query = $this->db->query('select * from invoice_type_list where invoice_type_id="' . $id . '"');
        $data = $this->db->assoc($query);
        if (!empty($data['depot_options_ids'])) {
            $query = $this->db->query('select Depot_ID as id,
                concat_ws(" - ",Depot_Code,Depot_Name) as text
                from tbl_stock_depot_warehouse 
                where Depot_ID in (' . $data['depot_options_ids'] . ')');
            while ($row = $this->db->assoc($query)) {
                $data['depot_arr'][] = $row;
            }
        }
        if (!empty($data['class_options_ids'])) {
            $query = $this->db->query('select Class_ID as id,
                Class_Name as text
                from tbl_pricing_class 
                where Class_ID in (' . $data['class_options_ids'] . ')');
            while ($row = $this->db->assoc($query)) {
                $data['class_arr'][] = $row;
            }
        }
        if (!empty($data['salesman_ids'])) {
            $query = $this->db->query('select Employee_ID as id,
                concat_ws(" ",Employee_FirstName,Employee_MiddleName,Employee_LastName) as text
                from tbl_hrm_employee 
                where Employee_ID in (' . $data['salesman_ids'] . ')');
            while ($row = $this->db->assoc($query)) {
                $data['emp_arr'][] = $row;
            }
        }
        return $data;
    }

    public function invoice_type_search($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' where (invoice_type_name LIKE ? or invoice_type_name_actual LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        if (!empty($this->info['type'])) {
            $cond .= ' and type = "' . $this->info['type'] . '" ';
        }

        $query = $this->db->prepare_Stmt('select 
                                    invoice_type_id as id,
                                    ' . (!empty($this->info['is_actual']) ? 'invoice_type_name_actual' : 'invoice_type_name') . ' as text
                                from 
                                    tbl_invoice_types
                                ' . $cond . '
                                limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function monthly_year_sales_graph() {
        $data = array('month_year' => [], 'net_total' => []);
        $is_second_curr = (!empty($this->info['currency_id']) && $this->info['currency_id'] == 2 ? '1' : '0');
        $from_date = empty($this->info['start_date']) ? date('Y-m') : $this->info['start_date'];
        $to_date = empty($this->info['end_date']) ? date('Y-m') : $this->info['end_date'];
        $is_actual = $this->info['is_actual'];
        $tmp_date = $from_date;
        while ($tmp_date <= $to_date) {
            $data['month_year'][$tmp_date] = $tmp_date;
            $data['net_total'][$tmp_date] = 0;
            $tmp_date = date('Y-m', strtotime($tmp_date . '-01 +1Month'));
        }
        $query = $this->db->prepare_Stmt(" select DATE_FORMAT(Invoice_Date, '%Y-%m') as month_year ,
                sum((Invoice_Shipping + Invoice_Net_Total) * if('{$is_second_curr}'='1' ,second_currency_rate, current_rate)) as net_total
                from tbl_invoices where DATE_FORMAT(Invoice_Date, '%Y-%m') between ? and ? and is_actual = ? GROUP by DATE_FORMAT(Invoice_Date, '%Y-%m') "
                , [&$from_date, &$to_date, &$is_actual]);
        while ($row = $this->db->assoc($query)) {
            $data['month_year'][$row['month_year']] = $row['month_year'];
            $data['net_total'][$row['month_year']] = round($row['net_total'], 3);
        }
        $data['month_year'] = array_values($data['month_year']);
        $data['net_total'] = array_values($data['net_total']);
        //
        return $data;
    }

    public function monthly_year_sales_list() {
        $data = array('month_year' => [], 'net_total' => []);
        $is_second_curr = (!empty($this->info['currency_id']) && $this->info['currency_id'] == 2 ? '1' : '0');
        $from_date = empty($this->info['start_date']) ? date('Y') : $this->info['start_date'];
        $to_date = empty($this->info['end_date']) ? date('Y') : $this->info['end_date'];
        $is_actual = $this->info['is_actual'];
        $query = $this->db->prepare_Stmt(" select DATE_FORMAT(Invoice_Date, '%Y-%m') as month_year 
            ,sum((Invoice_Shipping + Invoice_Net_Total) * if('{$is_second_curr}'='1' ,second_currency_rate, current_rate)) as net_total 
                from tbl_invoices where YEAR(Invoice_Date) between ? and ? and is_actual = ? GROUP by DATE_FORMAT(Invoice_Date, '%Y-%m') "
                , [&$from_date, &$to_date, &$is_actual]);
        while ($row = $this->db->assoc($query)) {
            $data[$row['month_year']] = CommonFunctions::formatNumber($row['net_total']);
        }
        $years_arr = array();
        $tmp_date = $from_date;
        while ($tmp_date <= $to_date) {
            $years_arr[] = $tmp_date;
            $tmp_date++;
        }
        //
        return ['data' => $data, 'years' => $years_arr];
    }

    public function monthly_year_products_sales_list() {
        $data = array();
        $is_second_curr = (!empty($this->info['currency_id']) && $this->info['currency_id'] == 2 ? '1' : '0');
        $from_date = empty($this->info['start_date']) ? date('Y-m') : $this->info['start_date'];
        $to_date = empty($this->info['end_date']) ? date('Y-m') : $this->info['end_date'];
        $is_actual = $this->info['is_actual'];
        $months_arr = array();
        $tmp_date = $from_date;
        while ($tmp_date <= $to_date) {
            $months_arr[] = $tmp_date;
            $tmp_date++;
        }
        $query_total = '';
        if ($this->info['report_type'] == "1")
            $query_total = " ,UOM_Name , sum(d.Product_Quantity/uc.conversion_amount)  as total_record ";
        if ($this->info['report_type'] == "2")
            $query_total = " ,sum(Product_Total_Price * if('{$is_second_curr}'='1' ,second_currency_rate, current_rate)) as total_record ";
        $query = $this->db->prepare_Stmt(" select d.Product_ID ,concat(Product_Code,' - ',Product_Name) as prd_name  ,DATE_FORMAT(Invoice_Date, '%Y-%m') as month_year " . $query_total . "
                from  tbl_invoice_products_details d      
                INNER JOIN
                      tbl_invoices i
                on i.Invoice_ID_Auto = d.Invoice_ID_Auto
                INNER JOIN
                      tbl_stock_products p
                on p.Product_ID = d.Product_ID
                INNER JOIN
                      tbl_stock_uom u on (u.UOM_ID = if(p.default_sales_uom<>0,p.default_sales_uom,p.UOM_ID) )
                join tbl_uom_conversions uc on uc.Product_ID = d.Product_ID and uc.uom_from = if(p.default_sales_uom<>0,p.default_sales_uom,p.UOM_ID) 

                where DATE_FORMAT(Invoice_Date, '%Y-%m') between ? and ? and is_actual = ? GROUP by DATE_FORMAT(Invoice_Date, '%Y-%m'),d.product_ID "
                , [&$from_date, &$to_date, &$is_actual]);
        while ($row = $this->db->assoc($query)) {
            if (!isset($data[$row['Product_ID']]))
                $data[$row['Product_ID']] = array('name' => $row['prd_name'], 'month_year' => array());
            $data[$row['Product_ID']]['month_year'][$row['month_year']] = [($this->info['report_type'] == 1 ? CommonFunctions::formatNumber($row['total_record']) . ' ' . $row['UOM_Name'] : CommonFunctions::formatNumber($row['total_record']))];
        }

        //
        return ['data' => $data, 'months' => $months_arr];
    }

    public function monthly_sales_graph() {
        $data = array();
        $is_second_curr = (!empty($this->info['currency_id']) && $this->info['currency_id'] == 2 ? '1' : '0');
        $from_date = empty($this->info['start_date']) ? date('Y') : $this->info['start_date'];
        $to_date = empty($this->info['end_date']) ? date('Y') : $this->info['end_date'];
        $is_actual = $this->info['is_actual'];
        $query = $this->db->prepare_Stmt(" select DATE_FORMAT(Invoice_Date, '%Y-%m') as month_year 
            ,sum((Invoice_Shipping + Invoice_Net_Total) * if('{$is_second_curr}'='1' ,second_currency_rate, current_rate)) as net_total 
            from tbl_invoices where YEAR(Invoice_Date) between ? and ? and is_actual = ? GROUP by DATE_FORMAT(Invoice_Date, '%Y-%m') "
                , [&$from_date, &$to_date, &$is_actual]);
        while ($row = $this->db->assoc($query)) {
            $data[$row['month_year']] = round($row['net_total'], 3);
        }
        $years_arr = array();
        $tmp_date = $from_date;
        while ($tmp_date <= $to_date) {
            $years_arr[] = $tmp_date;
            $tmp_date++;
        }
        //
        return ['data' => $data, 'years' => $years_arr];
    }

    public function forcast_sales_report($from_date, $to_date, $supplier_id = null, $cat_id = null) {
        $data = array();
        //
        $order_ids = array();
        $order_cond = '';
        $prod_cond = '';
        if (!is_null($supplier_id) && $supplier_id != '') {
            $order_cond = ' and Supplier_ID = "' . $supplier_id . '" ';
            $prod_cond = ' and main_supplier_id = "' . $supplier_id . '" ';
        }
        if (!is_null($cat_id) && $cat_id != '') {
            $prod_cond = ' and Category_ID = "' . $cat_id . '" ';
        }
        $query = $this->db->query('select Order_ID,concat(sale_prefix,Order_ID_Auto) as order_nb
            from tbl_purchase_order 
            where is_sales = 0 and is_quotation = 0 and is_converted = 0 ' . $order_cond . '
            order by Order_Date desc limit 5');
        while ($row = $this->db->assoc($query)) {
            $order_ids[$row['Order_ID']] = $row;
        }
        //
        $dates = array();
        $from = $from_date;
        while ($from <= $to_date) {
            $str_from = str_replace('-', '_', $from);
            $dates[] = $str_from;
            $from = date("Y-m", strtotime("+1 month", strtotime($from)));
            //                echo $from.'==';
        }
//        echo"<pre>";die(print_r($dates));
        //
        $prod_arr = array();
        $prod_uom_dflt_rate = array();
        $query = $this->db->query('select Product_ID,Product_Code,Product_Name,UOM_Name,
            (Product_Quantity/default_view_rate) as Product_Quantity,default_view_rate
            from tbl_stock_products p join tbl_stock_uom u on u.UOM_ID = p.default_view_uom_id 
            where 1=1 ' . $prod_cond);
        while ($row = $this->db->assoc($query)) {
            $prod_id = $row['Product_ID'];
            $prod_uom_dflt_rate[$prod_id] = $row['default_view_rate'];
            unset($row['default_view_rate']);
            unset($row['Product_ID']);
            $prod_arr[$prod_id] = $prod_id;
            $data[$prod_id] = $row;

            if (!empty($order_ids)) {
                foreach ($order_ids as $order_id => $order_row) {
                    $data[$prod_id]['order_' . $order_id] = 0;
                }
            }
            $data[$prod_id]['order_total'] = 0;
            if (!empty($dates)) {
                foreach ($dates as $date) {
                    $data[$prod_id][$date] = 0;
                }
            }
            $data[$prod_id]['total_sold'] = 0;
        }

        //
        if (!empty($order_ids) && !empty($prod_arr)) {
            $query = $this->db->query('select Order_ID,Item_ID,sum(Quantity) as quantity 
                from tbl_purchase_order_details where Order_ID in (' . implode(',', array_keys($order_ids)) . ') 
                and Item_ID in (' . implode(',', $prod_arr) . ') group by Order_ID,Item_ID');
            while ($row = $this->db->assoc($query)) {
                $data[$row['Item_ID']]['order_' . $row['Order_ID']] = ($row['quantity'] / $prod_uom_dflt_rate[$row['Item_ID']]);
                $data[$row['Item_ID']]['order_total'] += ($row['quantity'] / $prod_uom_dflt_rate[$row['Item_ID']]);
            }
        }
        //
        if (!empty($prod_arr)) {
            $query = $this->db->query('select d.Product_ID,sum(d.Product_Quantity) as quantity,
                DATE_FORMAT(i.Invoice_Date,"%Y") as year,DATE_FORMAT(i.Invoice_Date,"%m") as month
                from tbl_invoice_products_details d join tbl_invoices i
                on i.Invoice_ID_Auto = d.Invoice_ID_Auto where Product_ID in (' . implode(',', $prod_arr) . ')
                and i.Invoice_Date between "' . ($from_date . '-01') . '" and "' . ($to_date . '-31') . '"
                group by year(i.Invoice_Date),month(i.Invoice_Date),d.Product_ID
                order by i.Invoice_Date asc
                ');
            while ($row = $this->db->assoc($query)) {
                $data[$row['Product_ID']][$row['year'] . '_' . $row['month']] = ($row['quantity'] / $prod_uom_dflt_rate[$row['Product_ID']]);
                $data[$row['Product_ID']]['total_sold'] += ($row['quantity'] / $prod_uom_dflt_rate[$row['Product_ID']]);
            }
        }
        $data_final = array();
        foreach ($data as $row) {
            $data_final[] = array_values($row);
        }
        //
        return ['data' => $data_final, 'orders' => $order_ids];
    }

    public function get_inv_to_transfer($inv_id) {
        $data = array();
        $entry_ids_array = array();
        $query = $this->db->query('SELECT i.Depot_ID as Request_To
          from tbl_invoices i where i.Invoice_ID_Auto= "' . $inv_id . '"');
        $data['main'] = $this->db->assoc($query);
        //
        $query_transfer = $this->db->query('select * from tbl_stock_request where invoice_auto_id = "' . smc_escape($inv_id) . '"');
        $row_trans = $this->db->rowsno($query_transfer);
        $data['main']['inv_transfered'] = !empty($row_trans) ? 1 : 0;

        //
        $query = $this->db->query('SELECT d.Entery_ID,d.Product_Quantity as Request_Qty,
            d.Item_Quantity_Current as Current_Quantity,
           d.UOM_ID as Request_UOM,d.Product_ID,p.Product_Code,p.Product_Name,p.is_lot,p.is_serial,p.is_service,
           c.Cat_ID,c.Cat_Name,p.Status_ID as product_status,u.conversion_amount,d.expiry_date,
           p.is_expiry,d.lot_nb,d.serial_nb,
           (if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)+d.Product_Quantity) as total_default_quantity
            From tbl_invoice_products_details d
            inner join tbl_stock_products p on d.Product_ID = p.Product_ID
            inner join tbl_uom_conversions u
            on u.Product_ID = d.Product_ID and d.UOM_ID = u.uom_from
            left join tbl_stock_product_location l
            on l.Location_Product_ID = d.Product_ID and l.Product_Depot_ID = "' . $data['main']['Request_To'] . '"
            join tbl_product_cat c on c.Cat_ID = p.Category_ID 
            Where d.Invoice_ID_Auto = "' . $inv_id . '"');
        $prod_ids = array();
        while ($row = $this->db->assoc($query)) {
            $data['Request'][$row['Entery_ID']] = $row;
            $prod_ids[$row['Product_ID']] = $row['Product_ID'];
            $entry_ids_array[] = $row['Entery_ID'];
        }
        if (!empty($entry_ids_array)) {
            $entry_ids_str = implode(',', $entry_ids_array);
            $criteria_details_query = $this->db->query('select  details.Entery_ID,
                                                            crit_details.criteria_detail_id,
                                                            crit_details.criteria_detail_name, 
                                                            details.criteria_note,
                                                            crit_details.criteria_id
                                                    from  tbl_invoice_product_criteria details
                                                    inner join tbl_product_criteria_detail crit_details
                                                    using(criteria_detail_id)
                                                    where details.Entery_ID IN (' . $entry_ids_str . ')
                                                    ');
            while ($row = $this->db->assoc($criteria_details_query)) {
                $data['Request'][$row['Entery_ID']]['criteria'][] = $row;
            }
        }
        if (!empty($prod_ids)) {
            $query_uom = $this->db->query('select uom_from,Product_ID from tbl_uom_conversions where Product_ID in(' . implode(',', $prod_ids) . ')');
            while ($row_uom = $this->db->assoc($query_uom)) {
                $data['uoms'][$row_uom['Product_ID']][] = $row_uom['uom_from'];
            }
        }
//        echo"<pre>";
//                die(print_r($data));
        return $data;
    }
    public function last_invoice_number() {
        $cond = '';
        if($this->permissions->hasPermission('Branches')){
            $cond .=  '';
        }else{
            $cond .= ' and  branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
        }


        $query_sales= $this->db->query('select Invoice_ID,invoice_prefix,Invoice_Date from tbl_invoices where 1=1 '.$cond.' order by Invoice_ID_Auto DESC limit 1');
        $sales_row = $this->db->assoc($query_sales);
        return $sales_row['invoice_prefix'].$sales_row['Invoice_ID'];

    }
    public function get_total_sales_invoices2($from_date, $to_date) {
        $cond = '';
        if(isset($from_date) && isset($to_date)){
            $cond .= ' AND Invoice_Date between "' . $from_date. '" and"' . $to_date . '" ';

        }

        $query = $this->db->prepare_Stmt('select Invoice_Date as date,current_rate,
            sum(Invoice_Net_Total*current_rate) as net_total,
            sum(Invoice_Net_Total*second_currency_rate) as second_net_total,
            Invoice_Currency as currency_id from tbl_invoices 
            where   is_committed = 1' . $cond );
        $row = $this->db->assoc($query);
        $data = array('net_total' => 0, 'second_net_total' => 0);
        $data['net_total'] = CommonFunctions::formatNumber($row['net_total']);
        $data['second_net_total'] = CommonFunctions::formatNumber($row['second_net_total']);
        return $data;
    }

}
