<?php

class Invoicepos {

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

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

    /**
     * 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->ware_house_depot = new WarehouseDepot();
        $this->permissions = new Permissions(Session::getUserID());
    }

    /**
     * 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 getData() {
        return $this->info;
    }

    public function createPOS($other = false) {
        if (!$other || !$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $is_actual = !isset($this->info['is_actual']) ? 0 : $this->info['is_actual'];
        $today = Date::getToday();
        $check = CommonFunctions::check_lock_data(['type' => 'invoice', 'start_date' => $today, 'is_actual' => $is_actual]);

        //$check = JV::checkCurrentYear($today, $today, $is_actual);
        if ($check !== '') {
            $error = array();
            $error[0] = $check;
            return $error;
        }


        //        $this->db->query('START TRANSACTION');
        $sales_account = smc_session()['user_accounts']['sales_account_id'];
        
        //status:
        //0->unpaid
        //1->partially_paid
        //2->paid
        //3->ordered
        //4->returned
        //5->on road
        //6-> cancelled
        $default_depot_id = (smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id']);
        $default_depot_branch_id = CommonBusiness::getBranchByDepot($default_depot_id);
        $depot_id = !empty($this->info['delivery_depot']) ? $this->info['delivery_depot'] : $default_depot_id;
        //        echo $this->info['delivery_depot'].'=='.$depot_id;
        $branch_id = CommonBusiness::getBranchByDepot($depot_id);
        //if($branch_id != smc_session()['default_setting']['default_branch_id']){
        if ($branch_id != $default_depot_branch_id) {
            $product_ids = implode(',', $this->info['product_ids']);
            $returned_products = Product::check_product_branches($branch_id, $product_ids);
            if (!empty($returned_products))
                return ['product_branches' => $returned_products];
        }
        $bone_nb = self::getBonNum($today);
        $Customer_ID = $this->info['Customer_ID'];
        $reservation_id = NULL;
        $default_hotel_customer = smc_session()['default_setting']['default_hotel_customer'];
        $hotel_data = smc_session()['default_setting']['hotel_database'];
        if (!empty($hotel_data) && !empty($default_hotel_customer) && !empty($this->info['reservation_id'])) {
            $Customer_ID = $default_hotel_customer;
            $reservation_id = !empty($this->info['reservation_id']) ? $this->info['reservation_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);
        $this->info['salesman_id'] = $Sales_ID;
        $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'];
        $prefix = (smc_session()['default_setting']['sync_type'] == 1 && smc_session()['default_setting']['default_branch_id'] != $branch_id) ? '' : (smc_session()['user_accounts']['serial_prefix'] ? smc_session()['user_accounts']['serial_prefix'] : $branch_prefix);
        //
        $inv_num = (smc_session()['default_setting']['sync_type'] == 1 && smc_session()['default_setting']['default_branch_id'] != $branch_id) ? '' : self::getMaxInvoice($prefix, $is_actual);
        $this->info['invoice_nb'] = $prefix . $inv_num;
        $Invoice_Due_Date = $today;
        $Invoice_Sub_Total = $this->info['Invoice_Sub_Total'];
        $is_app = isset($this->info['is_app']) ? $this->info['is_app'] : 0;
        $order_id_online = isset($this->info['is_app']) ? $this->info['order_id_online'] : 0;
        $Invoice_Discount = $this->info['Invoice_Discount'];
        $Discount_Amount = $this->info['Discount_Amount'];
        $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;
        $currency_query = $this->db->query('select Currency_ID from  tbl_pricing_class where Class_ID = "' . smc_session()['default_setting']['smart_diner_app_class_id'] . '"');
        $currency_id = $this->db->assoc($currency_query)['Currency_ID'];
        $Invoice_Currency = isset($this->info['is_app']) ? $currency_id : $this->info['Invoice_Currency'];
        $Delivery_Time = $this->info['Delivery_Date'] . ' ' . $this->info['Delivery_Time'];
        $service_percant = smc_session()['default_setting']['pos_service'];
        $service_value = $this->info['service_value'];
        $is_delivery = $this->info['is_delivery'];
        $cash_cat_amount = $this->info['cash_cat_amount'];
        $mydate = date("Y-m-d H:i:s");
        $this->info['date_created'] = $mydate;
        $this->info['created_logged_id'] = $this->info['Logged_ID'];
        $this->info['Invoice_Date'] = $today;
        $this->info['Invoice_Due_Date'] = $today;
        //        $status = $this->info['Invoice_Status'];
        $this->info['rate'] = CurrencyFactory::getLastExRate($Invoice_Currency);
        $this->info['second_rate'] = CurrencyFactory::getSecondCurrencyLastExRate($Invoice_Currency);
        $this->info['is_takeaway'] = isset($this->info['is_takeaway']) ? $this->info['is_takeaway'] : 0;
        $this->info['pending_status'] = isset($this->info['pending_status']) ? $this->info['pending_status'] : 0;
        $this->info['driver_id'] = isset($this->info['driver_id']) ? $this->info['driver_id'] : null;
        $status = 0;
        $remaining = $this->info['invoice_unpaid_amount'];
        //        echo $remaining.'==';
        //        die();
        if ((!empty($this->info['pending_status']) && $this->info['pending_status'] == 3) || $is_delivery == 1 || $this->info['is_takeaway'] == 1) {
            $status = 3;
        } else {

            if ($remaining == 0) {
                $status = 2;
            } elseif ($remaining < ($Invoice_Shipping + $Invoice_Net_Total)) {
                $status = 1;
            }
        }
        $inv_type = $this->info['invoice_type'];
        //        $temp_error = ["1"];ss
        //        $this->info['Persons_Count'] = $this->info['Persons_Count'] ? $this->info['Persons_Count'] : 0;
        $this->info['Invoice_Note'] = !empty($this->info['Invoice_Note']) ? $this->info['Invoice_Note'] : '';
        $this->info['customer_name_alias'] = !empty($this->info['customer_name_alias']) ? $this->info['customer_name_alias'] : '';

        $a = 0;
        $this->info['rate'] = CurrencyFactory::getLastExRate($Invoice_Currency);
        //        while (!empty($temp_error)) {
        $inv_num = $inv_num + $a;
        $bone_nb = $bone_nb + $a;

        $pos_customer_id = isset($this->info['is_app']) ? $this->info['account_id_online'] : ($this->info['pos_customer_id'] == 0 ? null : $this->info['pos_customer_id']);
        $this->info['pos_customer_id'] = $pos_customer_id;
        $address_id = isset($this->info['is_app']) ? $this->info['address_id_online'] : 0;

        $pos_customer_id_attribute = isset($this->info['is_app']) ? ' (select customer_id  from tbl_pos_customers where account_id_online = ?) ' : '?';
        $address_id_attribute = isset($this->info['is_app']) ? '(select address_id  from tbl_customer_address where address_id_online = ?)' : '?';

        $this->info['main_nb'] = $inv_num;
        $this->info['prefix'] = $prefix;
        $Class_ID = isset($this->info['is_app']) ? smc_session()['default_setting']['smart_diner_app_class_id'] : $this->info['Class_ID'];
        $order_note = !empty($this->info['main_order_note']) ? $this->info['main_order_note'] : '';
        $postponed_date_time = !empty($this->info['postponed_date_time']) ? $this->info['postponed_date_time'] : NULL;
        $is_committed = empty($this->info['is_committed']) ? 0 : 1;
        //        echo $is_committed.'===';die();
        $first_currency = $this->info['first_currency'];
        $second_currency = $this->info['second_currency'];
        $second_cash_cat_amount = $this->info['second_cash_cat_amount'];

        $exchange_rate_first_sec_arr = CurrencyFactory::returnExchangeRate($first_currency,$second_currency);
        $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($second_currency,$first_currency);
        $exchange_rate_sec_first = $exchange_rate_sec_first_arr[1] == '*' ? $exchange_rate_sec_first_arr[0] : (1 / $exchange_rate_sec_first_arr[0]);

        $second_cash_cat_amount_local_1 = $second_cash_cat_amount * $exchange_rate_first_sec;
        $second_cash_cat_amount_local_2 = $second_cash_cat_amount * $exchange_rate_sec_first;

        $second_cash_Invoice_Currency =  $second_currency;
        $second_cash_currency_rate = $exchange_rate_sec_first;
        $second_cash_Invoice_Paid_Amount = $second_cash_cat_amount;


        $first_cash_Invoice_Paid_Amount = $this->info['Paid_Amount'];
        $Paid_Amount = $this->info['Paid_Amount'] + $second_cash_cat_amount_local_2;
        $current_invoice_type = 1;
        $is_done = 1;
        if ($is_delivery == 1) {
            $current_invoice_type = 2;
        } else if ($this->info['is_takeaway'] == 1) {
            $is_done = 0;
            $current_invoice_type = 6;
        } else if ($this->info['table_id'] != 0) {
            $current_invoice_type = 4;
        } else if ($this->info['posponted_status'] != 0) {
            $current_invoice_type = 5;
        } else if ($status == 3 && $this->info['table_id'] == 0 && $is_delivery == 0) {
            $current_invoice_type = 3;
        } else if ($inv_type == 2 && $this->info['table_id'] == 0 && $is_delivery == 0) {
            $current_invoice_type = 1;
        }
        $is_printed = ($current_invoice_type == 3 && $this->info['kitchen_takeaway_delivery'] == 1) ? 1 : 0;
        $is_delivery_notified = 0;
        if (date('Y-m-d H:i') >= $Delivery_Time && smc_session()['default_setting']['autoprint_past_delivery'] && ($this->info['is_delivery'] == 1 || $this->info['is_takeaway'] == 1))
            $is_delivery_notified = 1;
        //
        $data = [&$inv_num, &$bone_nb, &$Customer_ID, &$Sales_ID, &$today, &$Invoice_Currency, &$Invoice_VAT, &$this->info['vat1_total'], &$this->info['vat2_total'],
            &$Invoice_Sub_Total, &$Invoice_Discount, &$Discount_Amount, &$Invoice_Net_Total, &$Invoice_Due_Date,
            &$mydate, &$mydate, &$this->info['Logged_ID'], &$this->info['Logged_ID'], &$this->year_id, &$this->info['Invoice_Description'],
            &$status, &$Invoice_Shipping, &$this->info['rate'], &$inv_type, &$Delivery_Time, &$is_delivery,
            &$this->info['Logged_ID'], &$this->info['table_id'],
            &$this->info['Persons_Count'], &$Paid_Amount, &$this->info['tax_amount'], &$depot_id,
            &$branch_id, &$prefix, &$Class_ID, &$pos_customer_id, &$sales_account, &$is_actual, &$service_percant,
            &$service_value, &$is_app, &$order_id_online, &$address_id, &$cash_cat_amount, &$this->info['posponted_status'], &$this->info['second_rate'], &$order_note, &$postponed_date_time, &$current_invoice_type, &$this->info['postponed_note'], &$is_printed,
            &$is_committed, &$is_delivery_notified, &$reservation_id, &$this->info['Invoice_Note'],
            &$this->info['customer_name_alias'], $this->info['driver_id'], $is_done,$second_cash_Invoice_Currency,$second_cash_currency_rate , $second_cash_Invoice_Paid_Amount ,$first_cash_Invoice_Paid_Amount
        ];
        $this->db->prepare_Stmt("INSERT INTO tbl_invoices (
            Invoice_ID,Bon_Number,Customer_ID,Sales_ID,Invoice_Date, Invoice_Currency,Invoice_VAT,vat1_total,vat2_total,
            Invoice_Sub_Total,Invoice_Discount, discount_amount,Invoice_Net_Total,Invoice_Due_Date,
            date_created,date_time,Logged_ID,created_logged_id,current_year_id,Invoice_Description,
            Invoice_Status,Invoice_Shipping,current_rate,Inv_Type,Delivery_Time,Is_Delivery,
            Close_ID,table_id,Persons_Count,Invoice_Paid_Amount,tax_amount,Depot_ID,
            branch_id,invoice_prefix,Class_ID,pos_customer_id,Account_ID,is_actual,
            service_percant,service_value,is_app,order_id_online,address_id,cash_amount,
            posponted_type,second_currency_rate,order_note,postponed_date_time,invoice_type,is_pos,
            postponed_note,is_printed,is_committed,is_invoice_total_on_shipping,is_delivery_notified,reservation_id,
            Invoice_Note,customer_name_alias,driver_id,is_done,second_cash_Invoice_Currency,second_cash_currency_rate,second_cash_Invoice_Paid_Amount,first_cash_Invoice_Paid_Amount) 
            VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?," . $pos_customer_id_attribute . ",?,?,?,?,?,?," . $address_id_attribute . ",?,?,?,?,?,?,1,?,?,?,0,?,?,?,?,?,?,?,?,?)

                            ", $data);

        //            $a++;
        //        }


        $Invoice_ID = $this->db->id();
        //                echo "====".$this->db->id().'===';
        $prod_arr = array();
        $prod_ids_arr = array();
        $overlap_arr = array();
        $expiry_valid_arr = array();
        $serial_valid_arr = array();
        $lot_valid_arr = array();
        $qty_valid_arr = array();
        $depot_arr = array($depot_id);
        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;
            $expiry_date = !empty($item["expiry_date"]) ? $item["expiry_date"] : NULL;
            $lot_nb = !empty($item['lot_nb']) ? $item['lot_nb'] : '';
            $serial_nb = !empty($item['serial_nb']) ? $item['serial_nb'] : '';
            $prod_ids_arr[] = $item['Product_ID'];
            $ProductID = $item["Product_ID"];
            //            $ProductQuantity = $item["Product_Quantity"];
            //            $ProductQuantity = Product::getConvertedQuantity($item['UOM_ID'], $item["Product_Quantity"], $ProductID);
            $ProductQuantityRate = Product::getConvertedQuantity($item['UOM_ID'], 1, $ProductID);
            $ProductQuantity = $ProductQuantityRate * $item["Product_Quantity"];
            $ProductDiscount = $item["Product_Disc"];
            $ProductNetPrice = $item["Net_Price"];
            $Product_Total_Price = smc_session()['default_setting']['products_without_vat'] == '1' ? $item["Total_Price"]  : $item["Total_Price"] - $item['vat_amount'] - $item['vat2_amount'];
            $item["Discount_Amount"] = array_key_exists("Discount_Amount", $item) ? $item["Discount_Amount"] : 0;
            $item["Added_Amount"] = array_key_exists("Added_Amount", $item) ? ($item["Added_Amount"] * $item["Product_Quantity"]) : 0;
            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => ($Product_Total_Price),
                "description" => '', "vat_amount" => ($item['vat_amount'] + $item['vat2_amount']));
            $is_service = !empty($item['is_service']) ? $item['is_service'] : 0;
            $costdata = [
                "Product_ID" => $ProductID,
                "Quantity" => $ProductQuantity,
                "Unit_Cost" => "",
                "unit_price" => $ProductNetPrice,
                "Currency_ID" => $Invoice_Currency,
                "date_time" => $mydate,
                "current_rate" => $this->info['rate'],
                "depot_id" => $depot_id,
                "trans_date" => $today,
                "current_quantity" => $item["Product_Quantity"],
                "uom_id" => $item["UOM_ID"],
                "is_actual" => 0,
                "expiry_date" => $expiry_date,
                "lot_nb" => $lot_nb,
                "serial_nb" => $serial_nb,
                "main_id" => $Invoice_ID,
                "is_service" => $is_service,
                "main_nb" => $prefix . $inv_num,
                "customer_id" => $Customer_ID
            ];
            //            $cost = CommonBusiness::addCostByType($costdata, "add_invoice");
            $unit_cost = 0;
            //CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $Invoice_Currency, $cost);
            //            $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']);
            //                    $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
            //                }
            //            }
            
        $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]);
        }

            $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["Product_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'];



             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'];

                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));
                }
                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"] = $link['current_quantity'];
                $costdata["Product_ID"] = $link['Product_ID'];
                $costdata["uom_id"] = $link['uom_id'];
                $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                $tmp_cst_qty = 0;
                if ($ProductQuantityRate != 0 && $item["Product_Quantity"] != 0)
                    $tmp_cst_qty = ($link['Quantity'] / ($ProductQuantityRate * $item["Product_Quantity"]));
                $cost = self::updateLinkQuantities($costdata, "add_invoice", $link['operation']) * $tmp_cst_qty;
                //                    echo $cost.='==';
                $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $Invoice_Currency, $cost);

                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_id][$expiry_date]))
                        $expiry_valid_arr['prod'][$link['Product_ID']][$depot_id][$expiry_date] = 0;
                    $expiry_valid_arr['prod'][$link['Product_ID']][$depot_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_id][$serial_nb]))
                        $serial_valid_arr['prod'][$link['Product_ID']][$depot_id][$serial_nb] = 0;
                    $serial_valid_arr['prod'][$link['Product_ID']][$depot_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_id][$lot_nb]))
                        $lot_valid_arr['prod'][$link['Product_ID']][$depot_id][$lot_nb] = 0;
                    $lot_valid_arr['prod'][$link['Product_ID']][$depot_id][$lot_nb]+= $link['Quantity'];
                }
                if (!empty($link['Quantity']) && empty(smc_session()['default_setting']['activate_pos_negative_sales'])) {
                    if (!isset($qty_valid_arr[$link['Product_ID']][$depot_id]))
                        $qty_valid_arr[$link['Product_ID']][$depot_id] = 0;
                    $qty_valid_arr[$link['Product_ID']][$depot_id]+= $link['Quantity'];
                 } 
            }
            //              $temp_error = $this->db->error();die(print_r($temp_error));
            $desc_item = isset($item['product_description']) ? $item['product_description'] : '';
            $reserve_date_from = !empty($item["reserve_date_from"]) ? $item["reserve_date_from"] : NULL;
            $reserve_date_to = !empty($item["reserve_date_to"]) ? $item["reserve_date_to"] : NULL;
            //die('hereeeeee');
            if (!empty($reserve_date_from) && !empty($reserve_date_to)) {
                //                echo 'hereee';
                $check = self::check_reservation_overlap($ProductID, $reserve_date_from, $reserve_date_to);
                if (!$check)
                    $overlap_arr[] = $item['prod_index'];
            }
           // return [$item['is_collected_points']];
            $hold = !empty($item['hold']) ? $item['hold'] : 0;
            $prod = [
                &$Invoice_ID,
                &$ProductID,
                &$ProductDiscount,
                &$ProductNetPrice,
                &$ProductQuantity,
                &$Product_Total_Price,
                &$unit_cost,
                &$item["Product_Quantity"],
                &$item["UOM_ID"],
                &$item["Discount_Amount"],
                &$item["vat_percent"],
                &$item["vat_amount"],
                &$item["vat2_percent"],
                &$item["vat2_amount"],
                &$item["Added_Amount"],
                &$expiry_date,
                &$reserve_date_from,
                &$reserve_date_to,
                &$desc_item, &$depot_id, &$item['total_tax'], &$lot_nb, &$serial_nb, &$mydate, $hold,
                &$item['is_collected_points']
            ];
            //            echo"<pre>";
            //            die(print_r($prod));
            $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (
                                                                        Invoice_ID_Auto,
                                                                        Product_ID,
                                                                        Product_Discount, 
                                                                        Product_Net_Price,
                                                                        Product_Quantity,
                                                                        Product_Total_Price,
                                                                        unit_cost,
                                                                        Item_Quantity_Current,
                                                                        UOM_ID,
                                                                        Discount_Amount,
                                                                        vat_percent,
                                                                        vat_amount,vat2_percent,vat2_amount,
                                                                        Added_Amount,
                                                                        expiry_date,reserve_from,reserve_to,
                                                                        product_description,depot_id,total_tax,
                                                                        lot_nb,serial_nb,date_created,hold,is_collected_points
                                                                        ) 
                                                                    VALUES (
                                                                        ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
                                                                        )
                    ", $prod);
            
            

            $detail_id = $this->db->id();
            $is_collect_points_query = $this->db->query('select * from tbl_invoice_products_details where Entery_ID ="' . $detail_id . '" ');
            $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;
                }
            }

            if (array_key_exists('criteria_details', $item)) {
                $arr = array();
                $arr['criteria_details'] = $item['criteria_details'];
                $arr['id'] = $detail_id;
                self::addInvDetailTags($arr);
            }
            if (array_key_exists('add_ons', $item)) {
                $arr = array();
                $arr['add_ons'] = $item['add_ons'];
                $arr['id'] = $detail_id;
                self::addInvDetailAddOns($arr);
            }
            if (array_key_exists('options_arr', $item)) {
                $arr = array();
                $arr['options_arr'] = $item['options_arr'];
                $arr['id'] = $detail_id;
                self::add_invoice_detail_options($arr);
            }
        }



      /*  if(smc_session()['default_setting']['cleaning_collected_points'] == 1){
            $this->db->prepare_Stmt('update tbl_customers set collected_points = 0, date_collected_point = NULL
            where date_collected_point < DATE_SUB(NOW(), INTERVAL 3 MONTH)');        
        } */



        if (!empty($expiry_valid_arr)) {

            $expiry_valid = CommonBusiness::validate_expiry_qty_exist($expiry_valid_arr, $depot_arr);
            if (!empty($expiry_valid)) {
                $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)) {
                $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)) {
                $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)) {
                $this->db->query('ROLLBACK');
                return ['qty_error', $qty_valid];
            }
        }
        if (!empty($overlap_arr)) {
            $this->db->query("ROLLBACK");
            return ['overlapp' => $overlap_arr];
        }
        $prod_str = implode(',',$prod_ids_arr);
        $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $sales_account, $Invoice_Discount, smc_session()['user_accounts']['sales_ship_account_id'], $this->info['Invoice_Shipping'], $this->info['tax_amount']);
        //$error= $this->db->error();
        //                        echo 'hereee<pre>';
        //                        print_r($error);die();
        $arr = ['type' => 'inv', 'main_id' => $Invoice_ID, 'action' => 0, 'date_time' => $mydate,
            'user_id' => $this->info['Logged_ID']];
        CommonFunctions::add_user_log($arr);
        $error = $this->db->error();
        if (!$other) {
            if (empty($error)) {
                //if invoice [cash|generate] and not pending [kitchen|park]
                // invoice type or table and not kitchen
                if ($inv_type == 2 && $this->info['pending_status'] != 3) {
                    $this->info['Invoice_ID_Auto'] = $Invoice_ID;
                    $error = self::payInvoice($prod_trans_arr);
                    return $error;
                }
                $this->db->query("COMMIT");
                //                die($this->info['pending_status'].'==='.$current_invoice_type.'=='.smc_session()['default_setting']['sumatra_print'].'===');
                if (smc_session()['default_setting']['sumatra_print'] == 1 &&
                        (($this->info['pending_status'] == 3 && $current_invoice_type == 4) || // table and kitchen
                        (!empty($this->info['kitchen_takeaway_delivery']) && $this->info['kitchen_takeaway_delivery'] == 1)// park and kitchen
                        || $is_delivery_notified)   //delivery or takeway with passed time & settings
                ) {
                    //                    die('here');
                    self::printPOSInvoice($Invoice_ID, $inv_type);
                    return $Invoice_ID;
                } else {
                    //                    die('there');
                    return $Invoice_ID;
                }
            } else {
                $this->db->query("ROLLBACK");
                return $error;
            }
            //            if (empty($error)) {
            //               
            //                $this->db->query("COMMIT");
            //                if ((smc_session()['sumatra_print'] == 1 && $this->info['pending_status'] != 3 && $inv_type != 1) ||  (smc_session()['default_setting']['activate_smart_diner'] == 1 && $this->info['pending_status'] != 3))  {
            //                    self::printPOSInvoice($Invoice_ID, $inv_type);
            //                } else {
            //                    return $Invoice_ID;
            //                }
            //            } else {
            //                $this->db->query("ROLLBACK");
            //                return $error;
            //            }
        }
        //           $error = $this->db->error();
        //die(print_r($error));
        return $error;
        //        return array_unique($error);
    }

    public function editInvoice($other = false) {
        //        echo"<pre>";
        //        die(print_r($this->info));
        $query_inv = $this->db->query('select * from tbl_invoices 
            where Invoice_ID_Auto = ?', [&$this->info['Invoice_ID_Auto']]);
        $row_inv = $this->db->assoc($query_inv);
        if (empty($row_inv)) {
            $error = array();
            $error[0] = CommonLanguage::getMessage('invoice_not_available');
            return $error;
        }
        //in case of table and retrive we re-fill table since it is empty..
        if (empty($this->info['table_id']) && !empty($row_inv['table_id']))
            $this->info['table_id'] = $row_inv['table_id'];
        //
        $is_actual = !isset($this->info['is_actual']) ? 0 : $this->info['is_actual'];
        $this->info['Invoice_Date'] = date('Y-m-d');
        $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 (!$other || !$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');

        $default_depot_id = (smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id']);
        $default_depot_branch_id = CommonBusiness::getBranchByDepot($default_depot_id);
        $depot_id = $default_depot_id;
        $new_depot_id = !empty($this->info['delivery_depot']) ? $this->info['delivery_depot'] : $depot_id;
        $new_branch_id = CommonBusiness::getBranchByDepot($new_depot_id);
        if ($default_depot_branch_id != $new_branch_id) {
            $product_ids = implode(',', $this->info['product_ids']);
            $returned_products = Product::check_product_branches($new_branch_id, $product_ids);
            if (!empty($returned_products))
                return ['product_branches' => $returned_products];
        }
        $mydate = date("Y-m-d H:i:s");
        $today = date('Y-m-d');
        $Invoice_ID = $this->info['Invoice_ID_Auto'];
        //        $ref_num = "Inv." . $this->info['Invoice_ID_Auto'];
        $this->info['Logged_ID'] = Session::getUserID();
        $Invoice_Currency = $this->info['Invoice_Currency'];
        $inv_type = $this->info['invoice_type'];
        //        $depot_id = null;
        //        $depot_id = smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'];
        $paid = $this->info['Paid_Amount'];
        //        $remaining = $this->info['invoice_unpaid_amount'];
        //        $customer_account = self::getCustomerAccount($this->info['Customer_ID']);
        //        $customerAccount = $customer_account['Account_ID'];
        //        $customerAccount = $this->info['account_customer_id'];
        // how to get customer account
        $status = 0;
        $remaining = $this->info['invoice_unpaid_amount'];
        //        echo $remaining.'==';
        //        die();
        if ((!empty($this->info['pending_status']) && $this->info['pending_status'] == 3) || $this->info['Invoice_Status'] == 3) {
            $status = 3;
        } else {
            if ($remaining == 0) {
                $status = 2;
            } elseif ($remaining < ($this->info['Invoice_Shipping'] + $this->info['Invoice_Net_Total'])) {
                $status = 1;
            }
        }
        $old_ids = [];
        $new_old_ids = [];
        $removed_quantities = [];
        $added_quantities = [];
        $edit_array = array();
        //select all old produuct data to be compared with later(incase quantity changed or entire row delete)
        //ro print added items (or quantity) and deleted items (quantities)
        //        $edit_array = self::dataEditOrder($Invoice_ID, ($deleted_orders + $removed_quantities + $added_quantities));
        //        echo '<pre>';
        //        print_r($deleted_orders);
        //        print_r($removed_quantities);
        //        print_r($added_quantities);
        $jv_query = $this->db->query("SELECT DISTINCT JV_ID,Current_Ex_Rate,Transaction_Date FROM tbl_accounting_transactions  WHERE main_id='" . $this->info['Invoice_ID_Auto'] . "' AND main_type= 'inv' ");
        $jv_assoc = $this->db->assoc($jv_query);
        if (count($jv_assoc) > 0)
            $jv = $jv_assoc['JV_ID'];
        else
            $jv = JV::returnJV(0);
        $query_num = $this->db->query('select concat(invoice_prefix,Invoice_ID) as inv_num,invoice_prefix,is_printed,
            Invoice_ID,created_logged_id,date_created,Invoice_Due_Date,Invoice_Date,reservation_id from tbl_invoices where Invoice_ID_Auto = "' . $this->info['Invoice_ID_Auto'] . '" ');
        $num_arr = $this->db->assoc($query_num);
        $this->info['invoice_nb'] = $num_arr['inv_num'];
        $this->info['main_nb'] = $num_arr['Invoice_ID'];
        $this->info['prefix'] = $num_arr['invoice_prefix'];
        $this->info['date_created'] = $num_arr['date_created'];
        $this->info['created_logged_id'] = $num_arr['created_logged_id'];
        $this->info['Invoice_Due_Date'] = $num_arr['Invoice_Due_Date'];
        $this->info['Invoice_Date'] = $num_arr['Invoice_Date'];


        //        $rate
        $this->db->prepare_Stmt("DELETE FROM tbl_accounting_transactions  WHERE main_id= ? AND main_type= 'inv' ", [&$this->info['Invoice_ID_Auto']]);

        $customer_pos_id = empty($this->info['pos_customer_id']) ? null : $this->info['pos_customer_id'];
        $this->info['rate'] = CurrencyFactory::getLastExRate($this->info['Invoice_Currency']);
        $this->info['second_rate'] = CurrencyFactory::getSecondCurrencyLastExRate($this->info['Invoice_Currency']);
        $this->info['is_takeaway'] = isset($this->info['is_takeaway']) ? $this->info['is_takeaway'] : 0;
        $this->info['posponted_status'] = isset($this->info['posponted_status']) ? $this->info['posponted_status'] : 0;
        $service_percant = smc_session()['default_setting']['pos_service'];
        $service_value = $this->info['service_value'];
        $sales_account = smc_session()['user_accounts']['sales_account_id'];
        $cash_cat_amount = $this->info['cash_cat_amount'];
        $Delivery_Time = $this->info['Delivery_Date'] . ' ' . $this->info['Delivery_Time'];
        $order_note = !empty($this->info['main_order_note']) ? $this->info['main_order_note'] : '';
        $postponed_date_time = !empty($this->info['postponed_date_time']) ? $this->info['postponed_date_time'] : NULL;
        $this->info['driver_id'] = !empty($this->info['driver_id']) ? $this->info['driver_id'] : NULL;
        $is_delivery = $this->info['is_delivery'];
        //        echo $is_delivery;
        //        echo $inv_type;
        //        echo $status;
        //        die('jjj');
        $current_invoice_type = 1;
        if ($is_delivery == 1) {
            $current_invoice_type = 2;
        } else if ($this->info['is_takeaway'] == 1) {
            $current_invoice_type = 6;
        } else if ($this->info['table_id'] != 0) {
            $current_invoice_type = 4;
        } else if ($this->info['posponted_status'] != 0) {
            $current_invoice_type = 5;
        } else if ($status == 3 && $this->info['table_id'] == 0 && $is_delivery == 0) {
            $current_invoice_type = 3;
        } else if ($inv_type == 2 && $this->info['table_id'] == 0 && $is_delivery == 0) {
            $current_invoice_type = 1;
        }
        $this->info['is_printed_before'] = $num_arr['is_printed'];
        $is_printed = $current_invoice_type == 3 ? ($this->info['kitchen_takeaway_delivery'] == 1 ? 1 : 0) : $this->info['is_printed_before'];
        $edit_inv_arr = $this->edit_old_details_qty_cost($this->info['Invoice_ID_Auto']);
        $is_delivery_notified = 0;
        if (date('Y-m-d H:i') >= $Delivery_Time && smc_session()['default_setting']['autoprint_past_delivery'] && ($this->info['is_delivery'] == 1 || $this->info['is_takeaway'] == 1))
            $is_delivery_notified = 1;
        $this->info['Sales_ID'] = !empty($this->info['Sales_ID']) ? $this->info['Sales_ID'] : 0;
        $this->info['salesman_id'] = $this->info['Sales_ID'];
        $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;

        $reservation_id = NULL;
        $default_hotel_customer = smc_session()['default_setting']['default_hotel_customer'];
        $hotel_data = smc_session()['default_setting']['hotel_database'];
        $is_hotel_sync = 0;
        if (!empty($hotel_data) && !empty($default_hotel_customer) && !empty($this->info['reservation_id'])) {
            $this->info['Customer_ID'] = $default_hotel_customer;
            $reservation_id = $this->info['reservation_id'];
        }
        if (!empty($hotel_data) && $reservation_id != $num_arr['reservation_id']) {
            $is_hotel_sync = 2;
        }

        
        $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;
        }

        $this->info['Invoice_Note'] = !empty($this->info['Invoice_Note']) ? $this->info['Invoice_Note'] : '';
        $this->info['customer_name_alias'] = !empty($this->info['customer_name_alias']) ? $this->info['customer_name_alias'] : '';
        $up_main = [
            &$this->info['Customer_ID'],
            &$customer_pos_id,
            &$Invoice_Currency, // &$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'],
            &$paid,
            &$status,
            &$this->info['Logged_ID'],
            &$this->info['truck'],
            &$this->info['Invoice_Description'],
            &$this->info['Invoice_Shipping'],
            &$Delivery_Time,
            &$this->info['rate'],
            &$second_rate2, //&$this->info['second_rate'],
            &$this->info['Class_ID'],
            &$mydate,
            &$sales_account,
            &$service_percant,
            &$service_value,
            &$this->info['Persons_Count'],
            &$cash_cat_amount, &$this->info['Invoice_Due_Date'], &$this->info['posponted_status'],
            &$order_note,
            &$postponed_date_time,
            &$current_invoice_type,
            &$this->info['postponed_note'], &$new_depot_id, &$is_printed, &$is_delivery_notified,
            &$this->info['Sales_ID'],
            &$reservation_id,
            &$this->info['Invoice_Note'],
            &$this->info['customer_name_alias'],
            &$is_hotel_sync, $this->info['driver_id'], $is_delivery,
            &$this->info['Invoice_ID_Auto']
        ];
        $this->db->prepare_Stmt("UPDATE 
                                    tbl_invoices 
                                SET
                                    Customer_ID = ?,
                                    pos_customer_id = ?,
                                    Invoice_Currency = ?,
                                    Invoice_VAT = ?,vat1_total=?,vat2_total=?,
                                    Invoice_Sub_Total = ?,
                                    Invoice_Discount = ?,
                                    discount_amount = ?,
                                    Invoice_Net_Total = ?,
                                    tax_amount=?,
                                    Invoice_Paid_Amount = ?,
                                    Invoice_Status = ?,
                                    Logged_ID = ?,
                                    truck = ?,
                                    Invoice_Description=?,
                                    Invoice_Shipping=?,
                                    Delivery_Time=?,
                                    current_rate = ?,second_currency_rate=?,
                                    Class_ID = ?,
                                    date_time = ?,
                                    Account_ID = ?,
                                    service_percant = ?,
                                    service_value = ?,
                                    Persons_Count = ?,
                                    cash_amount = ?,Invoice_Due_Date=?,posponted_type=?,is_main_transfer = 0,
                                    order_note=?,
                                    postponed_date_time = ?,
                                    invoice_type = ?,
                                    postponed_note = ?,Depot_ID = ?,is_printed = ?,
                                    is_delivery_notified=?,Sales_ID=?,
                                    reservation_id = ?,
                                    Invoice_Note = ?,
                                    customer_name_alias = ?,
                                    is_hotel_sync = ?,driver_id=?,Is_Delivery=?
                                WHERE 
                                    Invoice_ID_Auto = ?

                 ", $up_main);
        //echo"<pre>";die(print_r($up_main));
        //        $old_date_time = $today;


        $update_stock = [&$this->info['Invoice_ID_Auto']];

        $uom_ids = array();
        $entry_old_arr = array();
        $query = $this->db->query("SELECT * FROM tbl_invoice_products_details WHERE Invoice_ID_Auto = '" . $Invoice_ID . "'");
        while ($row = $this->db->assoc($query)) {
            //save array with each row (key-->entry-id, value --->quantity)
            $entry_old_arr[$row['Entery_ID']] = $row;
            $old_ids[$row['Entery_ID']] = $row['Product_Quantity'];
            $uom_ids[$row['Entery_ID']]['uom_id'] = $row['UOM_ID'];
            $uom_ids[$row['Entery_ID']]['conv'] = $row['Product_Quantity'] / $row['Item_Quantity_Current'];
        }
        $k = 0;
        $prod_ids_arr = array();
        $related_entries_arr = array();
        $overlap_arr = array();
        $current_entry_ids = array();
        $new_entry_ids = array();

        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($new_depot_id);
        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;
            $expiry_date = !empty($item["expiry_date"]) ? $item["expiry_date"] : NULL;
            $prod_ids_arr[] = $item['Product_ID'];
            $ProductID = $item["Product_ID"];
            //            $ProductQuantity = Product::getConvertedQuantity($item['UOM_ID'], $item["Product_Quantity"], $ProductID);
            $ProductQuantityRate = Product::getConvertedQuantity($item['UOM_ID'], 1, $ProductID);
            $ProductQuantity = $ProductQuantityRate * $item['Product_Quantity'];

            $ProductDiscount = $item["Product_Disc"];
            $ProductNetPrice = $item["Net_Price"];
            $Product_Total_Price = smc_session()['default_setting']['products_without_vat'] == '1' ? $item["Total_Price"] : $item["Total_Price"] - $item['vat_amount'] - $item['vat2_amount'];
            $item["Added_Amount"] = $item["Added_Amount"] * $item["Product_Quantity"];
            $lot_nb = !empty($item['lot_nb']) ? $item['lot_nb'] : '';
            $serial_nb = !empty($item['serial_nb']) ? $item['serial_nb'] : '';
            $is_service = !empty($item['is_service']) ? $item['is_service'] : 0;

            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => ($Product_Total_Price),
                "description" => '', "vat_amount" => ($item['vat_amount'] + $item['vat2_amount']));
            $unit_cost = 0;
            $costdata = [
                "Product_ID" => $ProductID,
                "Quantity" => $ProductQuantity,
                "Unit_Cost" => "",
                "unit_price" => $ProductNetPrice,
                "Currency_ID" => $Invoice_Currency,
                "date_time" => $mydate,
                "current_rate" => $this->info['rate'],
                "depot_id" => $new_depot_id,
                "trans_date" => $today,
                "current_quantity" => $item["Product_Quantity"],
                "uom_id" => $item["UOM_ID"],
                "is_actual" => 0,
                "expiry_date" => $expiry_date,
                "lot_nb" => $lot_nb,
                "serial_nb" => $serial_nb,
                "main_id" => $this->info['Invoice_ID_Auto'],
                "is_service" => $is_service,
                "main_nb" => $this->info['invoice_nb'],
                "customer_id" => $this->info['Customer_ID']
            ];
            $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);
            $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'];

            
            
            //               echo"<pre>";die(print_r($product_links));
            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'];

                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));
                }
                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"] = $link['current_quantity'];
                $costdata["Product_ID"] = $link['Product_ID'];
                $costdata["uom_id"] = $link['uom_id'];
                $costdata['is_inverse'] = $link['is_oprtn_inverse'];
                //Yousif and replace from InvoiceSMCCustom to Invoice
                $depot_detail_id = !empty($item['depot_id']) ? $item['depot_id'] : $depot_id;
                $tmp_cst_qty = 0;
                if ($ProductQuantityRate != 0 && $item["Item_Quantity"] != 0)
                    $tmp_cst_qty = ($link['Quantity'] / ($ProductQuantityRate * $item["Item_Quantity"]));
                $cost = self::updateLinkQuantities($costdata, "edit_invoice_new", $link['operation']) * $tmp_cst_qty;
                //                    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'])) {
                    $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']['activate_pos_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'];
                }
            }
            //            echo"<pre>";
            //            die(print_r($costdata));
            //            $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $ProductID . '"');
            //            $unit_cost = 0;
            //            $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);
            //                }
            //            }

            $reserve_date_from = !empty($item["reserve_date_from"]) ? $item["reserve_date_from"] : NULL;
            $reserve_date_to = !empty($item["reserve_date_to"]) ? $item["reserve_date_to"] : NULL;
            $desc_item = isset($item['product_description']) ? $item['product_description'] : '';
            $hold = !empty($item['hold']) ? $item['hold'] : 0;

            if ($item['Entery_ID'] > 0) {
                $uom_ids[$item['Entery_ID']]['uom_id'] = $item['UOM_ID'];
                $uom_ids[$item['Entery_ID']]['conv'] = $ProductQuantityRate;

                if (!empty($reserve_date_from) && !empty($reserve_date_to)) {
                    $check = self::check_reservation_overlap($ProductID, $reserve_date_from, $reserve_date_to, $item["Entery_ID"]);
                    if (!$check)
                        $overlap_arr[] = $item['prod_index'];
                }
                //if entery_id > 0 then edit on old data
                //if old quantity > edited quantity
                if ($old_ids[$item['Entery_ID']] > $ProductQuantity)
                //save amount must be deleted for current row
                    $removed_quantities[$item['Entery_ID']] = ($old_ids[$item['Entery_ID']] - $ProductQuantity);
                elseif ($old_ids[$item['Entery_ID']] < $ProductQuantity)
                //save amount must be added to current row
                    $added_quantities[$item['Entery_ID']] = ($ProductQuantity - $old_ids[$item['Entery_ID']]) . "p";
                $new_old_ids[$item['Entery_ID']] = $ProductQuantity;
                //                echo $hold.'==';
                //$details_kitchen_status = $entry_old_arr[$item["Entery_ID"]]['details_kitchen_status'];
                //update direct done status & done qty ... also about whole invoice...
                $done_qty = min($item["Product_Quantity"], $entry_old_arr[$item["Entery_ID"]]['done_qty']);
                if ($item["Product_Quantity"] > $done_qty) {
                    $details_kitchen_status = 0;
                    $current_entry_ids[] = $item["Entery_ID"];
                } else
                    $details_kitchen_status = 1;
                //
                $prod = [
                    &$ProductDiscount,
                    &$ProductNetPrice,
                    &$ProductQuantity,
                    &$Product_Total_Price,
                    &$item["Product_Quantity"],
                    &$item["UOM_ID"],
                    &$item["Discount_Amount"],
                    &$item["Added_Amount"],
                    &$expiry_date,
                    &$reserve_date_from, &$reserve_date_to,
                    &$desc_item, &$new_depot_id, &$item['total_tax'], &$lot_nb, &$serial_nb,
                    $item['vat_percent'], $item['vat_amount'], $item['vat2_percent'], $item['vat2_amount'], $unit_cost,
                    $hold, &$done_qty, &$details_kitchen_status,
                    &$item["Entery_ID"]
                ];


                //update product details
                $this->db->prepare_Stmt("UPDATE 
                                                tbl_invoice_products_details 
                                            SET
                                                Product_Discount = ?, 
                                                Product_Net_Price = ?,
                                                Product_Quantity = ?,
                                                Product_Total_Price = ?,
                                                Item_Quantity_Current = ?,
                                                UOM_ID = ?,
                                                Discount_Amount = ?,
                                                Added_Amount = ?,
                                                expiry_date = ?,
                                                reserve_from=?,reserve_to=?,
                                                product_description = ?,depot_id=?,total_tax=?,
                                                lot_nb=?,serial_nb=?,vat_percent=?,vat_amount=?,vat2_percent=?,vat2_amount=?,
                                                unit_cost=?,hold=?,
                                                done_qty = ?,
                                                details_kitchen_status = ?
                                            WHERE 
                                                Entery_ID = ?
                            ", $prod);
                $this->db->prepare_Stmt("DELETE FROM tbl_invoice_product_criteria where Entery_ID =?", [&$item["Entery_ID"]]);
                $this->db->prepare_Stmt("DELETE FROM tbl_invoice_product_add_ons where Entery_ID =?", [&$item["Entery_ID"]]);
                $this->db->prepare_Stmt("DELETE FROM tbl_invoice_product_options where invoice_detail_id =?", [&$item["Entery_ID"]]);
                if (array_key_exists('criteria_details', $item)) {
                    $arr = array();
                    $arr['criteria_details'] = $item['criteria_details'];
                    $arr['id'] = $item["Entery_ID"];
                    self::updateTags($arr);
                }
                if (array_key_exists('add_ons', $item)) {
                    $arr2 = array();
                    $arr['add_ons'] = $item['add_ons'];
                    $arr['id'] = $item["Entery_ID"];
                    self::addInvDetailAddOns($arr2);
                }
                if (array_key_exists('options_arr', $item)) {
                    $arr2 = array();
                    $arr2['options_arr'] = $item['options_arr'];
                    $arr2['id'] = $item["Entery_ID"];
                    self::add_invoice_detail_options($arr2);
                }
            } else {    //new rows
                if (!empty($reserve_date_from) && !empty($reserve_date_to)) {
                    $check = self::check_reservation_overlap($ProductID, $reserve_date_from, $reserve_date_to);
                    if (!$check)
                        $overlap_arr[] = $item['prod_index'];
                }
                //new row added
                $prod = [
                    &$Invoice_ID,
                    &$ProductID,
                    &$ProductDiscount,
                    &$ProductNetPrice,
                    &$ProductQuantity,
                    &$Product_Total_Price,
                    &$unit_cost,
                    &$item["Product_Quantity"],
                    &$item["UOM_ID"],
                    &$item["Discount_Amount"],
                    &$item["vat_percent"],
                    &$item["vat_amount"],
                    &$item["vat2_percent"],
                    &$item["vat2_amount"],
                    &$item["Added_Amount"],
                    &$expiry_date, &$reserve_date_from, &$reserve_date_to, &$desc_item, &$new_depot_id,
                    &$item['total_tax'], &$lot_nb, &$serial_nb, &$mydate, $hold
                ];
                //insert new items
                $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (
                                    Invoice_ID_Auto,
                                    Product_ID,
                                    Product_Discount, 
                                    Product_Net_Price,
                                    Product_Quantity,
                                    Product_Total_Price,
                                    unit_cost,
                                    Item_Quantity_Current,
                                    UOM_ID,
                                    Discount_Amount,
                                    vat_percent,
                                    vat_amount,vat2_percent,
                                    vat2_amount,
                                    Added_Amount,
                                    expiry_date,reserve_from,reserve_to,
                                    product_description,depot_id,total_tax,
                                    lot_nb,serial_nb,date_created,hold
                                    ) 
                                VALUES (
                                    ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
                                    )
                            ", $prod);
                $detail_id = $this->db->id();
                $new_entry_ids[] = $detail_id;
                $uom_ids[$detail_id]['uom_id'] = $item['UOM_ID'];
                $uom_ids[$detail_id]['conv'] = $ProductQuantityRate;



                if (empty($item['relate_entry_id'])) {
                    //add new items to added quantity array (p: to be checked later for print (if amount added or deleted))
                    $added_quantities[$detail_id] = $ProductQuantity . "p";
                } else {
                    //                    //if entery_id > 0 then edit on old data
                    //                    //if old quantity > edited quantity
                    //                    if ($old_ids[$item['relate_entry_id']] > $ProductQuantity)
                    //                    //save amount must be deleted for current row
                    //                        $removed_quantities[$item['relate_entry_id']] = ($old_ids[$item['relate_entry_id']] - $ProductQuantity);
                    //                    elseif ($old_ids[$item['relate_entry_id']] < $ProductQuantity)
                    //                    //save amount must be added to current row
                    //                        $added_quantities[$item['relate_entry_id']] = ($ProductQuantity - $old_ids[$item['relate_entry_id']]) . "p";
                    //                    $new_old_ids[$item['relate_entry_id']] = $ProductQuantity;
                    if (!isset($related_entries_arr[$item['relate_entry_id']][$detail_id]))
                        $related_entries_arr[$item['relate_entry_id']][$detail_id] = 0;
                    $related_entries_arr[$item['relate_entry_id']][$detail_id] += $ProductQuantity;
                }

                if (array_key_exists('criteria_details', $item)) {
                    //                $item['tags']['id'] = $detail_id;
                    $arr = array();
                    $arr['criteria_details'] = $item['criteria_details'];
                    $arr['id'] = $detail_id;
                    self::addInvDetailTags($arr);
                }
                if (array_key_exists('add_ons', $item)) {
                    $arr2 = array();
                    $arr['add_ons'] = $item['add_ons'];
                    $arr['id'] = $item["Entery_ID"];
                    self::addInvDetailAddOns($arr2);
                }
                if (array_key_exists('options_arr', $item)) {
                    $arr2 = array();
                    $arr2['options_arr'] = $item['options_arr'];
                    $arr2['id'] = $item["Entery_ID"];
                    self::add_invoice_detail_options($arr2);
                }
            }
            if ($item['is_transfer'] > 0 and $item['transfered_quantity'] > 0) {
                //for transferitems,split case just to update full array of products
                if ($item['Entery_ID'] == 0)
                    $this->info['products'][$k]['Entery_ID'] = $detail_id;
                if ($item['transfered_quantity'] > $item['Product_Quantity'])
                    $this->info['products'][$k]['transfered_quantity'] = $item['Product_Quantity'];
            }
            $k++;
        }
        if (!empty($expiry_valid_arr)) {
            $expiry_valid = CommonBusiness::validate_expiry_qty_exist($expiry_valid_arr, $depot_arr);
            if (!empty($expiry_valid)) {
                $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)) {
                $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)) {
                $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)) {
                $this->db->query('ROLLBACK');
                return ['qty_error', $qty_valid];
            }
        }
        foreach ($related_entries_arr as $relate_entry_id => $relate_dtl) {
            foreach ($relate_dtl as $new_detail_id => $relate_qty) {
                //if main detail row still exist
                if (isset($new_old_ids[$relate_entry_id])) {
                    if (!empty($removed_quantities[$relate_entry_id])) {
                        $tmp_qty = min($removed_quantities[$relate_entry_id], $relate_qty);
                        $removed_quantities[$relate_entry_id] -= $tmp_qty;
                        if (empty($removed_quantities[$relate_entry_id]))
                            unset($removed_quantities[$relate_entry_id]);
                        $relate_qty -= $tmp_qty;
                    }
                    if ($relate_qty > 0) {
                        if (empty($added_quantities[$relate_entry_id]))
                            $added_quantities[$relate_entry_id] = 0;
                        $relate_qty += doubleval(str_replace("p", "", $added_quantities[$relate_entry_id]));
                        $added_quantities[$relate_entry_id] = $relate_qty . "p";
                    }
                } else  //in case of main row deleted
                    $added_quantities[$new_detail_id] = $relate_qty . "p";
            }
        }

        if (!empty($overlap_arr)) {
            $this->db->query("ROLLBACK");
            return ['overlapp' => $overlap_arr];
        }
        $deleted_orders = array_diff_key($old_ids, $new_old_ids);
        //ro print added items (or quantity) and deleted items (quantities)
        if (!empty($deleted_orders + $removed_quantities + $added_quantities)) {
            $edit_array = self::dataEditOrder($Invoice_ID, ($deleted_orders + $removed_quantities + $added_quantities), $uom_ids);
        }
        //        echo '<pre>';
        //        print_r($edit_array);

        if (!empty($current_entry_ids) || !empty($new_entry_ids)) {
            $this->db->prepare_Stmt('update tbl_invoices 
                                    set order_kitchen_status = 0 
                                    where Invoice_ID_Auto = ?', [&$Invoice_ID]);
        }
        //        echo"<pre>";
        //        print_r($edit_array);
        //                die(print_r($edit_array));
        $this->info['edited_array'] = $edit_array;
        if (count($deleted_orders) > 0) {
            //delete deleted product details from invoice details
            $delete = implode(", ", array_keys($deleted_orders));
            if (smc_session()['default_setting']['activate_void_items_pos'] == 1 && !empty($this->info['void_items'])) {
                self::insertVoidItems($delete, $this->info['void_items'], $depot_id);
            }
            $this->db->prepare_Stmt("DELETE FROM tbl_invoice_products_details WHERE Entery_ID IN ({$delete})");
        }

        $prod_str = implode( ',',$prod_ids_arr);
        $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $sales_account, $this->info['Invoice_Discount'], smc_session()['user_accounts']['sales_ship_account_id'], $this->info['Invoice_Shipping'], $this->info['tax_amount']);


        $arr = ['type' => 'inv', 'main_id' => $this->info['Invoice_ID_Auto'], 'action' => 1, 'date_time' => $mydate,
            'user_id' => $this->info['Logged_ID']];
        CommonFunctions::add_user_log($arr);
        $error = $this->db->error();
        if (!$other) {
            if (empty($error)) {
                //        die(print_r($error));
                if ($inv_type == 2 && $this->info['pending_status'] != 3) {
                    if (!empty($edit_array) && (($current_invoice_type == 4) || ($current_invoice_type == 1 && $this->info['is_printed_before'] == 1))) {
                        self::printRemovedDeleted($edit_array);
                    }
                    $error = self::payInvoice($prod_trans_arr, $jv);
                    return $error;
                }

                $this->db->query("COMMIT");
                if (smc_session()['default_setting']['sumatra_print'] == 1) {
                    $is_kitchen_takeaway = !empty($this->info['kitchen_takeaway_delivery']) && $this->info['kitchen_takeaway_delivery'] == 1;
                    if (($is_kitchen_takeaway && $this->info['is_printed_before'] != 1) || $is_delivery_notified) {
                        self::printPOSInvoice($Invoice_ID, $inv_type);
                    }
                    if (!empty($edit_array) && ($current_invoice_type == 4 || ($is_kitchen_takeaway && $this->info['is_printed_before'] == 1))) {
                        self::printRemovedDeleted($edit_array);
                    }
                }

                //                if ((smc_session()['default_setting']['sumatra_print'] == 1 && $this->info['pending_status'] != 3 && $inv_type != 1) ||
                //                    smc_session()['default_setting']['activate_smart_diner'] == 1 ||
                //                    (!empty($this->info['kitchen_takeaway_delivery']) && $this->info['kitchen_takeaway_delivery'] == 1)) {
                //                    self::printPOSInvoice($Invoice_ID, $inv_type);
                //                    if (!empty($edit_array) && smc_session()['default_setting']['sumatra_print'] == 1 &&
                //                        ($this->info['pending_status'] != 3 || ($this->info['pending_status'] == 3 && $this->info['is_printed_before'] == 1) || $current_invoice_type == 4)) {
                //                        self::printRemovedDeleted($edit_array);
                //                    }
                //                }
                return $Invoice_ID;
            } else {
                $this->db->query("ROLLBACK");
                return $error;
            }
        }
        return $error;
    }

    public function insertVoidItems($ids, $void_items, $depot_id) {
        $data_time = date('Y-m-d H:i:s');
        $user_id = smc_session()['user_logged_id'];
        $query = $this->db->query("select * from tbl_invoice_products_details where Entery_ID IN ({$ids})");
        while ($row = $this->db->assoc($query)) {
            $this->db->prepare_Stmt("Insert into tbl_invoice_products_void 
             (Invoice_ID_Auto,Product_ID,Product_Total_Price,Item_Quantity_Current,UOM_ID,product_description,date_time,user_id) 
             VALUES (?,?,?,?,?,?,?,?)", [&$row['Invoice_ID_Auto'], &$row['Product_ID'], &$row['Product_Total_Price'],
                &$row['Item_Quantity_Current'], &$row['UOM_ID'], &$row['product_description'],
                &$data_time, &$user_id]);
            if (!empty($void_items)) {
                $type_id = $void_items[$row['Entery_ID']]['type_id'];
                $damage_reason = $void_items[$row['Entery_ID']]['reason_title'];
                if ($type_id == 2) {
                    $data = array(
                        'Depot_ID' => $depot_id,
                        'is_actual' => 0,
                        'note' => $damage_reason,
                        'Products' => [['UOM_ID' => $row['UOM_ID'],
                        'Product_ID' => $row['Product_ID'],
                        'quantity' => $row['Item_Quantity_Current']]]
                    );
//                    $data = ['UOM_ID' => $row['UOM_ID'], 'Product_ID' => $row['Product_ID'],
//                        'Damaged_Quantity' => $row['Item_Quantity_Current'], 'logged_id' => $user_id,
//                        'Depot_ID' => $depot_id, ];
                    $this->ware_house_depot->stop_transaction_start_end = true;
//                    $this->ware_house_depot->setData($data)->addDamagedQuantities();
                    $this->ware_house_depot->setData($data)->add_damage();
                }
            }
        }
    }

    //    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 submitOnlineOrders() {
        $accounts = array_key_exists('accounts', $this->info) ? $this->info['accounts'] : [];
        $addresses = array_key_exists('addresses', $this->info) ? $this->info['addresses'] : [];
        $orders = array_key_exists('orders', $this->info) ? $this->info['orders'] : [];
        //        echo '<pre>';
        //        print_r($accounts);
        //        print_r($addresses);

        $this->db->query('START TRANSACTION');

        foreach ($accounts as $account) {
            $this->db->prepare_Stmt("INSERT INTO  tbl_pos_customers (customer_name,
                                                                                customer_phone,
                                                                                customer_email,
                                                                                account_id_online
                                                                                ) 
                                                                            VALUES (?,?,?,?)
                            ", [&$account['customer_name'], &$account['customer_phone'],
                &$account['customer_email'], &$account['account_id_online']]);
        }
        foreach ($addresses as $address) {
            $this->db->prepare_Stmt("INSERT INTO  tbl_customer_address (customer_id,
                                                                                address_name,
                                                                                address_id_online
                                                                                ) 
                                            VALUES ((select customer_id from tbl_pos_customers where account_id_online = ?),?,?)
                            ", [&$address['account_id_online'], &$address['address_name'],
                &$address['address_id_online']]);
        }
        foreach ($orders as $order) {
            $error = $this->setdata($order)->createPOS(true);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query("COMMIT");
        } else {
            $this->db->query("ROLLBACK");
        }
        return $error;
    }

    public function getMaxInvoice($prefix, $is_actual) {

        $yearid = $is_actual ? $this->year_id_actual : $this->year_id;
        $query = $this->db->query('SELECT Invoice_ID AS Entry_ID 
            FROM tbl_invoices where current_year_id = "' . $yearid . '" '
                . 'and invoice_prefix = "' . $prefix . '" and is_actual = "' . $is_actual . '" order by Invoice_ID desc limit 1');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $Invoice = $row['Entry_ID'] + 1;
        else
            $Invoice = 1;

        return $Invoice;
    }

    public function getBonNum($today) {
        $cond = ' ';
        if (smc_session()['default_setting']['bon_number_generation'] == 0)
            $cond .= ' and Invoice_Date = "' . $today . '" ';
        else if (smc_session()['default_setting']['bon_number_generation'] == 1)
            $cond .= ' and year(Invoice_Date) = "' . date('Y', strtotime($today)) . '" ';
        else if (smc_session()['default_setting']['bon_number_generation'] == 2) {
            $query_shift = $this->db->query('select close_time from tbl_end_of_shift 
                where type = 1 order by close_time desc limit 1');
            $row_shift = $this->db->assoc($query_shift);
            $close_time = !empty($row_shift) ? $row_shift['close_time'] : '';
            $cond .= ' and date_created > "' . $close_time . '" ';
        }
        $query = $this->db->query('SELECT Bon_Number AS Entry_ID FROM tbl_invoices WHERE true ' . $cond . ' order by Bon_Number desc limit 1');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $bon_num = $row['Entry_ID'] + 1;
        else
            $bon_num = 1;

        return $bon_num;
    }

    //    public function editPOSOrder($other = false) {
    //        //in case we edited the invoice for any reason different than direct edit(ex: split, transfer, merge...)
    //        if (!$other)
    //            $this->db->query('START TRANSACTION');
    //        $Customer_ID = $this->info['Customer_ID'];
    //        $Invoice_Sub_Total = $this->info['Invoice_Sub_Total'];
    //        $Invoice_Discount = $this->info['Invoice_Discount'];
    //        $Invoice_Net_Total = $this->info['Invoice_Net_Total'];
    //        $Invoice_VAT = $this->info['Invoice_VAT'];
    //        $Invoice_Currency = $this->info['Invoice_Currency'];
    //
    //        $mydate = date("Y-m-d h:i:s a");
    //        //update main data about the invoice
    //        $data = [
    //            &$Customer_ID,
    //            &$Invoice_Currency,
    //            &$Invoice_VAT,
    //            &$Invoice_Sub_Total,
    //            &$Invoice_Discount,
    //            &$Invoice_Net_Total,
    //            &$mydate,
    //            &$this->info['Invoice_Description'],
    //            &$this->info['Invoice_Note'],
    //            &$this->info['Invoice_ID_Auto']
    //        ];
    //        $this->db->prepare_Stmt("UPDATE tbl_invoices 
    //                                            SET
    //
    //                                                    Customer_ID = ?, 
    //                                                    Invoice_Currency = ?,
    //                                                    Invoice_VAT = ?,
    //                                                    Invoice_Sub_Total = ?,
    //                                                    Invoice_Discount = ?, 
    //                                                    Invoice_Net_Total = ?,
    //                                                    date_time = ?,
    //                                                    Invoice_Description = ?,
    //                                                    Invoice_Note = ?
    //                                            WHERE 
    //                                                Invoice_ID_Auto = ?
    //
    //                            ", $data);
    //
    //        $Invoice_ID = $this->info['Invoice_ID_Auto'];
    //
    //
    //        $old_ids = [];
    //        $new_old_ids = [];
    //        $removed_quantities = [];
    //        $added_quantities = [];
    //        //select all old produuct data to be compared with later(incase quantity changed or entire row delete)
    //        $query = $this->db->query("SELECT * FROM tbl_invoice_products_details WHERE Invoice_ID_Auto = '" . $Invoice_ID . "'");
    //        while ($row = $this->db->assoc($query)) {
    //            //save array with each row (key-->entry-id, value --->quantity)
    //            $old_ids[$row['Entery_ID']] = $row['Product_Quantity'];
    //        }
    //        $k = 0;
    //        foreach ($this->info['products'] as $item) {
    //            $ProductID = $item["Product_ID"];
    //            $ProductQuantity = Product::getConvertedQuantity($item['UOM_ID'], $item["Product_Quantity"], $ProductID);
    //            $ProductDiscount = $item["Product_Disc"];
    //            $ProductNetPrice = $item["Net_Price"];
    //            $Product_Total_Price = $item["Total_Price"];
    //            $item["Added_Amount"] = $item["Added_Amount"] * $item["Product_Quantity"];
    //            if ($item['Entery_ID'] > 0) {
    //                //if entery_id > 0 then edit on old data
    //                //if old quantity > edited quantity
    //                if ($old_ids[$item['Entery_ID']] > $item['Product_Quantity'])
    //                    //save amount must be deleted for current row
    //                    $removed_quantities[$item['Entery_ID']] = ($old_ids[$item['Entery_ID']] - $item['Product_Quantity']);
    //                elseif ($old_ids[$item['Entery_ID']] < $item['Product_Quantity'])
    //                    //save amount must be added to current row
    //                    $added_quantities[$item['Entery_ID']] = ($item['Product_Quantity'] - $old_ids[$item['Entery_ID']]) . "p";
    //                $new_old_ids[$item['Entery_ID']] = $item['Product_Quantity'];
    //                $prod = [
    //                    &$ProductDiscount,
    //                    &$ProductNetPrice,
    //                    &$ProductQuantity,
    //                    &$Product_Total_Price,
    //                    &$item["Product_Quantity"],
    //                    &$item["UOM_ID"],
    //                    &$item["Discount_Amount"],
    //                    &$item["Added_Amount"],
    //                    &$item["Entery_ID"]
    //                ];
    //                //update product details
    //                $this->db->prepare_Stmt("UPDATE 
    //                                                tbl_invoice_products_details 
    //                                            SET
    //                                                Product_Discount = ?, 
    //                                                Product_Net_Price = ?,
    //                                                Product_Quantity = ?,
    //                                                Product_Total_Price = ?,
    //                                                Item_Quantity_Current = ?,
    //                                                UOM_ID = ?,
    //                                                Discount_Amount = ?,
    //                                                Added_Amount = ?
    //                                            WHERE 
    //                                                Entery_ID = ?
    //                            ", $prod);
    //                if (array_key_exists('tags', $item)) {
    //                    $arr = array();
    //                    $arr['tags'] = $item['tags'];
    //                    $arr['id'] = $item["Entery_ID"];
    //                    self::updateTags($arr);
    //                }
    //            } else {
    //                //new row added
    //                $prod = [
    //                    &$Invoice_ID,
    //                    &$ProductID,
    //                    &$ProductDiscount,
    //                    &$ProductNetPrice,
    //                    &$ProductQuantity,
    //                    &$Product_Total_Price,
    //                    &$item["Product_Quantity"],
    //                    &$item["UOM_ID"],
    //                    &$item["Discount_Amount"],
    //                    &$item["vat_percent"],
    //                    &$item["vat_amount"],
    //                    &$item["Added_Amount"]
    //                ];
    //                //insert new items
    //                $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (
    //                                                                                Invoice_ID_Auto,
    //                                                                                Product_ID,
    //                                                                                Product_Discount, 
    //                                                                                Product_Net_Price,
    //                                                                                Product_Quantity,
    //                                                                                Product_Total_Price,
    //                                                                                Item_Quantity_Current,
    //                                                                                UOM_ID,
    //                                                                                Discount_Amount,
    //                                                                                vat_percent,
    //                                                                                vat_amount,
    //                                                                                Added_Amount
    //                                                                                ) 
    //                                                                            VALUES (
    //                                                                                ?,?,?,?,?,?,?,?,?,?,?,?
    //                                                                                )
    //                            ", $prod);
    //                $detail_id = $this->db->id();
    //                //add new items to added quantity array (p: to be checked later for print (if amount added or deleted))
    //                $added_quantities[$detail_id] = $item['Product_Quantity'] . "p";
    //
    //                if (array_key_exists('tags', $item)) {
    //                    $arr = array();
    //                    $arr['tags'] = $item['tags'];
    //                    $arr['id'] = $detail_id;
    //                    self::updateTags($arr);
    //                }
    //            }
    //            if ($item['is_transfer'] > 0 and $item['transfered_quantity'] > 0) {
    //                //for transferitems,split case just to update full array of products
    //                if ($item['Entery_ID'] == 0)
    //                    $this->info['products'][$k]['Entery_ID'] = $detail_id;
    //                if ($item['transfered_quantity'] > $item['Product_Quantity'])
    //                    $this->info['products'][$k]['transfered_quantity'] = $item['Product_Quantity'];
    //            }
    //
    //            $k++;
    //        }
    //
    //        //define deleted rows from invoice
    //        $deleted_orders = array_diff_key($old_ids, $new_old_ids);
    //
    //        //ro print added items (or quantity) and deleted items (quantities)
    //        $edit_array = self::dataEditOrder($Invoice_ID, ($deleted_orders + $removed_quantities + $added_quantities));
    //
    //        if (count($deleted_orders) > 0) {
    //            //delete deleted product details from invoice details
    //            $delete = implode(", ", array_keys($deleted_orders));
    //            $this->db->prepare_Stmt("DELETE FROM tbl_invoice_products_details WHERE Entery_ID IN (?)", [&$delete]);
    //        }
    //
    //
    //        $error = $this->db->error();
    //        if (!$other) {
    //            if (empty($error)) {
    //                self::printRemovedDeleted($edit_array);
    //                $this->db->query("COMMIT");
    //            } else {
    //                $this->db->query("ROLLBACK");
    //            }
    //        }
    //        return array_unique($error);
    //    }

    public function printRemovedDeleted($arr) {
        //        echo"<pre>";die(print_r($arr));
        if (smc_session()['default_setting']['pos_print_deleted_items_default_printer'] == 1) {
            $deleted_arr = array('main_invoice' => $arr['main_invoice']);
            $dflt_prntr = 'default';
            if (!empty($arr['default_printer_deleted'])) {
                $deleted_arr['printers'][$dflt_prntr]['deleted'] = $arr['default_printer_deleted'];
            }
            if (!empty($arr['default_printer_deleted_linked'])) {
                $deleted_arr['printers_linked'][$dflt_prntr]['deleted'] = $arr['default_printer_deleted_linked'];
            }
            self::posOrderRemovedAdded($deleted_arr, $dflt_prntr);
        }
        if (!empty($arr['printer_ids'])) {
            //            $bone_nb = $arr['main_invoice']['Bon_Number'];
            //            $pdf = new tcpdf('P', 'cm', array(8, 22), true, 'UTF-8', true);
            //            $file_array = array();
            //            $printer_array = array();
            //
            for ($i = 0; $i < count($arr['printer_ids']); $i++) {
                //                $pdf->_destroy();
                //                $pdf = new tcpdf('P', 'cm', array(8, 22), true, 'UTF-8', true);
                //                $filename = 'Order' . $bone_nb . '_' . (time() + rand());
                //                $file_array[] = $filename;
                //                                $printer_array[] = $arr['printer'][$i];

                self::posOrderRemovedAdded($arr, $arr['printer_ids'][$i]);
            }


            //            for ($i = 0; $i < count($file_array); $i++) {
            //                Forms::real_print($printer_array[$i], $file_array[$i], '');
            //            }
        }
    }

    public function addOrderPOS() {
        $this->db->query('START TRANSACTION');
        $mydate = date("Y-m-d h:i:s a");
        foreach ($this->info['products'] as $item) {
            $ProductID = $item["Product_ID"];
            $ProductQuantity = Product::getConvertedQuantity($item['UOM_ID'], $item["Product_Quantity"], $ProductID);
            $ProductDiscount = $item["Product_Disc"];
            $ProductNetPrice = $item["Net_Price"];
            $Product_Total_Price = $item["Total_Price"];
            $item["Added_Amount"] = $item["Added_Amount"] * $item["Product_Quantity"];
            $prod = [
                &$this->info['Invoice_ID_Auto'],
                &$ProductID,
                &$ProductDiscount,
                &$ProductNetPrice,
                &$ProductQuantity,
                &$Product_Total_Price,
                &$item["Product_Quantity"],
                &$item["UOM_ID"],
                &$item["Discount_Amount"],
                &$item["vat_percent"],
                &$item["vat_amount"],
                &$item["Added_Amount"],
                &$mydate
            ];
            $this->db->prepare_Stmt("INSERT INTO tbl_invoice_products_details (
                                                                        Invoice_ID_Auto,
                                                                        Product_ID,
                                                                        Product_Discount, 
                                                                        Product_Net_Price,
                                                                        Product_Quantity,
                                                                        Product_Total_Price,
                                                                        Item_Quantity_Current,
                                                                        UOM_ID,
                                                                        Discount_Amount,
                                                                        vat_percent,
                                                                        vat_amount,
                                                                        Added_Amount,
                                                                        date_created
                                                                        ) 
                                                                    VALUES (
                                                                        ?,?,?,?,?,?,?,?,?,?,?,?,?
                                                                        )
                    ", $prod);
            $sub_total = ($ProductNetPrice * $ProductQuantity);
            $data = [
                &$item["Item_VAT"],
                &$sub_total,
                &$item["Discount_Amount"],
                &$Product_Total_Price,
                &$this->info['Invoice_ID_Auto']
            ];
            $this->db->prepare_Stmt("UPDATE tbl_invoices 
                                            SET
                                                    Invoice_VAT = Invoice_VAT + ?,
                                                    Invoice_Sub_Total = Invoice_Sub_Total + ?,
                                                    Invoice_Discount = Invoice_Discount + ?, 
                                                    Invoice_Net_Total = Invoice_Net_Total + ?,is_main_transfer = 0
                                            WHERE 
                                                Invoice_ID_Auto = ?

                            ", $data);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query("COMMIT");
        } else {
            $this->db->query("ROLLBACK");
            return array_unique($error);
        }
    }

    public function printPOSInvoice($id, $invoice_type) {
        //        die('here');
        //note this ft. called on :: | pos create/edit invoice | reprint Order kitchen | print from delivery notification | 
        // $with_print :print invoice or not
        //$arr = self::getPOSorderToPrint($id);
        $invoice_obj = new Invoice();
        $fire_level = !empty($_GET['fire_level']) ? $_GET['fire_level'] : null;
        $arr = $invoice_obj->getInvoiceToPrint($id, $fire_level);
        //
        $is_splited_invoice = isset($this->info['is_splited_invoice']) && $this->info['is_splited_invoice'] == 1 ? 1 : 0;
        $is_printed_before = isset($this->info['printed_before']) && $this->info['printed_before'] == 1 ? 1 : 0;
        $with_print = (!empty($this->info['with_print']) && $this->info['with_print'] == 1);
        $reprint_order = isset($this->info['reprint_order']) && $this->info['reprint_order'] == 1 ? 1 : 0;
        $is_ktchn_tkwy_dlvry = (!empty($this->info['kitchen_takeaway_delivery']) && $this->info['kitchen_takeaway_delivery'] == 1);
        $is_delivery_notified = 0;
        $arr['main']['printed_before_class'] = ($is_printed_before == 1 ? '' : 'hidden');
        $arr['main']['rate_second_currency2'] = CurrencyFactory::getLastExRate(smc_session()['second_currency']['id']);
        $arr['main']['rate_second_currency'] = CurrencyFactory::getSecondCurrencyLastExRate(smc_session()['local_currency']);
        if (date('Y-m-d H:i:59') >= $arr['main']['Delivery_Time'] && smc_session()['default_setting']['autoprint_past_delivery'] && ($arr['main']['invoice_type'] == 2 || $arr['main']['invoice_type'] == 6))
            $is_delivery_notified = 1;
        //in case if called from 'ChangeDeliveryStatus' means when click print from order notification and need to print invoice with the order
        $is_delivery_invoice = $reprint_order && !empty(smc_session()['default_setting']['print_order_invoice_in_delivery_notification']) && ($arr['main']['invoice_type'] == 2 || $arr['main']['invoice_type'] == 6);
        //echo $is_splited_invoice.'<br>'.$is_printed_before.'<br>'.$with_print.'<br>'.$reprint_order.'<br>'.$is_ktchn_tkwy_dlvry;
        $is_edit = ($this->info['is_edited_invoice'] == 1);
        if (($this->info['pending_status'] != 3 && $invoice_type == 2 && $with_print) ||
                ($is_delivery_notified && $with_print && smc_session()['default_setting']['autoprint_past_delivery_with_invoice']) ||
                $is_delivery_invoice)
            $this->posInvPOS($arr['main']['Invoice_ID_Auto'], $arr);
        //table and open cash table no need to print kitchen
        //table,kitchen and edit no need to print order (print added deleted)
        //$reprint_order: reprint Order kitchen | print from delivery notification
        //$is_delivery_notified: delivery or takeway where time is passed and autoprint past delivery settings activated and with print
        if (smc_session()['print_pos_order'] && $is_splited_invoice == 0 &&
                ((!$is_edit && $arr['main']['invoice_type'] == 4 && ($this->info['open_cash_table'] == 0 || smc_session()['default_setting']['print_open_table_cash_order'] == 1) ) ||
                (!$is_printed_before && ($arr['main']['invoice_type'] == 1 || $is_ktchn_tkwy_dlvry)) ||
                ($reprint_order == 1) || ($is_delivery_notified && !$is_edit))
        ) {
            $ordr_arr = $arr;
            if (!empty(smc_session()['default_setting']['pos_print_order_group_identical']))
                $ordr_arr = $invoice_obj->merge_identical_invoice_rows($ordr_arr);
            for ($i = 0; $i < count($ordr_arr['printer_ids']); $i++) {
                self::posOrderPOS($ordr_arr, $ordr_arr['printer_ids'][$i]);
            }
        }

        if (!empty($arr['main']['entry_ids'])) {
            $this->db->prepare_Stmt('update tbl_invoice_products_details set is_fired = 1
                where Entery_ID in (' . (implode(',', $arr['main']['entry_ids'])) . ')');
        }
    }

    //this function is static since it is used in restaurant pos class
    public static function addInvDetailTags($info) {
        $db = DBConnectorFactory::loadDriver();
        $id = $info['id'];
        for ($i = 0; $i < count($info['criteria_details']); $i++) {
            $data = [
                &$id,
                &$info['criteria_details'][$i]['Quantity'],
                &$info['criteria_details'][$i]['criteria_detail_id'],
                &$info['criteria_details'][$i]['criteria_price'],
                &$info['criteria_details'][$i]['criteria_note']
            ];
            $db->prepare_Stmt("INSERT INTO
                                        tbl_invoice_product_criteria (
                                            Entery_ID,
                                            Quantity,
                                            criteria_detail_id,criteria_price,criteria_note
                                        )
                                        VALUES
                                        (?,?,?,?,?)
                    ", $data);
        }
    }

    public static function addInvDetailAddOns($info) {
        $db = DBConnectorFactory::loadDriver();
        $id = $info['id'];
        for ($i = 0; $i < count($info['add_ons']); $i++) {
            $data = [
                &$id,
                &$info['add_ons'][$i]['Quantity'],
                &$info['add_ons'][$i]['add_ons_details_id']
            ];
            $db->prepare_Stmt("INSERT INTO
                                        tbl_invoice_product_add_ons (
                                            Entery_ID,
                                            Quantity,
                                            add_ons_details_id
                                        )
                                        VALUES
                                        (?,?,?)
                    ", $data);
        }
    }

    public static function add_invoice_detail_options($info) {
        $db = DBConnectorFactory::loadDriver();
        $id = $info['id'];
        $option_arr = json_decode($info['options_arr'], true);
        for ($i = 0; $i < count($option_arr); $i++) {
            $data = [
                &$id,
                &$option_arr[$i]['option_id'],
                &$option_arr[$i]['product_id'],
                &$option_arr[$i]['uom_id'],
                &$option_arr[$i]['qty']
            ];
            $db->prepare_Stmt("INSERT INTO `tbl_invoice_product_options`( `invoice_detail_id`,
                option_id,`product_id`, `UOM_ID`, `option_quantity`) values(?,?,?,?,?)
                    ", $data);
        }
    }

    public function updateTags($info) {
        //        die('hello');
        $id = $info['id'];
        //        $this->db->prepare_Stmt("DELETE FROM tbl_invoice_product_criteria where Entery_ID =?", [&$id]);
        for ($i = 0; $i < count($info['criteria_details']); $i++) {
            $data = [
                &$id,
                &$info['criteria_details'][$i]['Quantity'],
                &$info['criteria_details'][$i]['criteria_detail_id'],
                &$info['criteria_details'][$i]['criteria_price'],
                &$info['criteria_details'][$i]['criteria_note'],
            ];
            $this->db->prepare_Stmt("INSERT INTO
                                        tbl_invoice_product_criteria (
                                            Entery_ID,
                                            Quantity,
                                            criteria_detail_id,
                                            criteria_price,
                                            criteria_note

                                        )
                                        VALUES
                                        (?,?,?,?,?)
                    ", $data);
        }
    }

    //    public function viewOrderedInvoices($time = '30') {
    //        $data = array();
    //
    //        $current_time = date("h:i:s a");
    //        $today = Date::getToday();
    //        $compared_time = date("h:i:s a", strtotime('+' . $time . ' minutes', strtotime($current_time)));
    //        $query = $this->db->query('SELECT * FROM tbl_invoices WHERE STR_TO_DATE(CONCAT("' . $today . '"," ",Delivery_Time), "%Y-%m-%d %h:%i:%s %p") <= STR_TO_DATE(CONCAT("' . $today . '"," ","' . $compared_time . '"), "%Y-%m-%d %h:%i:%s %p") AND Invoice_Status = 3');
    //        while ($row = $this->db->assoc($query))
    //            $data[] = $row;
    //        return $data;
    //    }

    public function getprinterName($id) {
        static $printers_arr = array();
        if (!isset($printers_arr[$id])) {
            $depot_id = !empty(smc_session()['user_accounts']['depot_id']) ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_setting']['default_depot_id'];
            $branch_id = CommonBusiness::getBranchByDepot($depot_id);
            $query = $this->db->query('SELECT printer_name FROM tbl_printers WHERE printer_id = "' . $id . '" and (branch_id = "" or concat_ws("",",",branch_id,",") LIKE  "%,' . $branch_id . ',%") ');
            $printer_row = $this->db->assoc($query);
            $printer_name = "";
            if (!empty($printer_row))
                $printer_name = str_replace("[user_ip]", $_SERVER['REMOTE_ADDR'], $printer_row['printer_name']);
            $printers_arr[$id] = $printer_name;
        }
        return $printers_arr[$id];
    }

    //    public function getPOSInvoices($id) {
    //        $data = array();
    //        $printers = array();
    //        $printers_id = array();
    //        $main_query = $this->db->query('SELECT * FROM pos_invoices WHERE Invoice_ID_Auto = "' . $id . '"');
    //        $main_arr = $this->db->assoc($main_query);
    //        $data['main_invoice'] = $main_arr;
    //        $query = $this->db->query('SELECT *, concat(Product_ID,UOM_ID) as unq,
    //                            Product_Net_Price*conversion_amount as Product_Net_Price,
    //                            group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG,
    //                            (`Item_Quantity_Current`) as Item_Quantity_Current,
    //                            (`Product_Total_Price`) as `Product_Total_Price`,
    //                            Bar_Code
    //                    FROM invoice_details 
    //                    left join tbl_invoice_product_criteria criteria using (`Entery_ID`) 
    //                    left join tbl_product_criteria_detail crit_detail using (`criteria_detail_id`) 
    //                    where `Invoice_ID_Auto` = "' . $id . '"
    //                    group by  `Entery_ID`');
    //        while ($row = $this->db->assoc($query)) {
    //            if (!empty($row['Printer_ID'])) {
    //                $printer_array = explode(",", $row['Printer_ID']);
    //                foreach ($printer_array as $item) {
    //                    $data['printers'][$item][] = $row;
    //                    if (!in_array($item, $printers_id)) {
    //                        $printers[] = self::getprinterName($item);
    //                        $printers_id[] = $item;
    //                    }
    //                }
    //            }
    //            $data['invoice_details'][$row['unq']]['Name'] = $row['Name'];
    //            $data['invoice_details'][$row['unq']]['Bar_Code'] = $row['Bar_Code'];
    //            $data['invoice_details'][$row['unq']]['UOM_Name'] = $row['UOM_Name'];
    //            $data['invoice_details'][$row['unq']]['Product_Net_Price'] = $row['Product_Net_Price'];
    //            if (array_key_exists('Item_Quantity_Current', $data['invoice_details'][$row['unq']])) {
    //                $data['invoice_details'][$row['unq']]['Item_Quantity_Current'] += $row['Item_Quantity_Current'];
    //                $data['invoice_details'][$row['unq']]['Product_Total_Price'] += $row['Product_Total_Price'];
    //            } else {
    //                $data['invoice_details'][$row['unq']]['Item_Quantity_Current'] = $row['Item_Quantity_Current'];
    //                $data['invoice_details'][$row['unq']]['Product_Total_Price'] = $row['Product_Total_Price'];
    //            }
    //        }
    //        $data['printer_ids'] = $printers_id;
    //        $data['printer'] = $printers;
    //        $data['Org'] = self::getOrganizationAddress();
    //        return $data;
    //    }

    public function dataEditOrder($id, $arr, $uom_ids) {
        //        echo"<pre>";
        //        print_r($uom_ids);
        //        die(print_r($arr));
        $data = array();
        $printers_id = array();
        $uom_names_arr = array();
        $query = $this->db->query('select * from tbl_stock_uom');
        while ($row = $this->db->assoc($query)) {
            $uom_names_arr[$row['UOM_ID']] = $row['UOM_Name'];
        }
        $main_query = $this->db->query('SELECT * FROM pos_invoices WHERE Invoice_ID_Auto = "' . $id . '"');
        $main_arr = $this->db->assoc($main_query);
        $main_arr['persons_count_class'] = $main_arr['Persons_Count'] != 0 ? '' : 'hidden';
        $main_arr['order_time'] = $main_arr['Is_Delivery'] == 0 ? $main_arr['date_time'] : $main_arr['Delivery_Time'];
        $main_arr['table_class'] = ($main_arr['Inv_Type'] == 2 && $main_arr['table_id'] != 0) ? '' : 'hidden';
        $main_arr['note_class'] = !empty($main_arr['Invoice_Description']) ? '' : 'hidden';
        $data['main_invoice'] = $main_arr;
        $entry_ids = implode(", ", array_keys($arr));
        //        SELECT *,
        //        concat(Product_ID,UOM_ID) as unq,
        //        Product_Net_Price*conversion_amount as Product_Net_Price,
        //        group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG,
        //        (`Item_Quantity_Current`) as Item_Quantity_Current,
        //        (`Product_Total_Price`) as `Product_Total_Price`
        //            FROM invoice_details 
        //            left join tbl_invoice_product_criteria criteria using (`Entery_ID`) 
        //            left join tbl_product_criteria_detail crit_detail using (`criteria_detail_id`) 
        //            where 
        //            `Invoice_ID_Auto` = "' . $id . '"
        //            group by 
        //            `Entery_ID`
        $query = $this->db->query(' SELECT *,
                                                concat(Product_ID,UOM_ID) as unq,
                                                group_concat(crit_detail.criteria_detail_name SEPARATOR "#$#") as TAG
                                        FROM invoice_details 
                                                left join tbl_invoice_details_tags using (`Entery_ID`) 
                                        left join 
                                                tbl_invoice_product_criteria criteria using (`Entery_ID`) 
                                        left join tbl_product_criteria_detail crit_detail using (`criteria_detail_id`) 
                                      where    
                                                `Entery_ID` in (' . $entry_ids . ')
                                       group by 
                                                `Entery_ID`');
        $tmp_items_arr = array();
        $item_ids_arr = array();
        while ($row = $this->db->assoc($query)) {
            $tag = $row['TAG'];
            $row['TAG'] = str_replace('#$#', ' , ', $tag);
            $row['tag_lines'] = str_replace('#$#', '<br/>', $tag);
            $tmp_items_arr[] = $row;
            $item_ids_arr[$row['Product_ID']] = $row['Product_ID'];
        }
        $item_link_arr = array();
        $link_query = $this->db->query('select k.*,u.UOM_Name,p.Product_Name,p.Printer_ID,p.Product_Arabic_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_Arabic_Name,p.Printer_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;
            }
        }
        //
        //                    echo"<pre>";die(print_r($tmp_items_arr));
        $old_hold = 0;
        foreach ($tmp_items_arr as $item_row) {
            $item_row['link_product_class'] = 'hidden';
            //if p then the current row is for added amounts else it is for deleted amounts
            $is_deleted = true;
            $item_row['Item_Quantity_Current'] = $arr[$item_row['Entery_ID']];
            $conv = !empty($uom_ids[$item_row['Entery_ID']]['conv']) ? $uom_ids[$item_row['Entery_ID']]['conv'] : 1;
            if (substr($arr[$item_row['Entery_ID']], -1) == "p") {
                $is_deleted = false;
                $item_row['Item_Quantity_Current'] = substr($item_row['Item_Quantity_Current'], 0, -1);
            }
            $item_row['numeric_current_qty'] = $item_row['Item_Quantity_Current'] / $conv;
            $item_row['Item_Quantity_Current'] = $item_row['numeric_current_qty'] . ' ' . $uom_names_arr[$uom_ids[$item_row['Entery_ID']]['uom_id']];
            $item_row['hold_class'] = $item_row['hold'] != $old_hold ? '' : 'hidden';
            $item_row['hold_text'] = $item_row['hold'];
            $item_row['fire_class'] = 'hidden';
            $item_row['fire_opposite_class'] = '';
            $old_hold = $item_row['hold'];
            if ($is_deleted) {
                $data['default_printer_deleted'][] = $item_row;
                if (empty($item_link_arr[$item_row['Product_ID']]))
                    $data['default_printer_deleted_linked'][] = $item_row;
            }
            //
            if (!empty($item_row['Printer_ID'])) {
                $printer_array = explode(",", $item_row['Printer_ID']);
                $item_row['link_product_class'] = 'hidden';
                foreach ($printer_array as $printer_id) {
                    if ($is_deleted) {
                        $data['printers'][$printer_id]['deleted'][] = $item_row;
                        if (empty($item_link_arr[$item_row['Product_ID']]))
                            $data['printers_linked'][$printer_id]['deleted'][] = $item_row;
                    }else {
                        $data['printers'][$printer_id]['added'][] = $item_row;
                        if (empty($item_link_arr[$item_row['Product_ID']]))
                            $data['printers_linked'][$printer_id]['added'][] = $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'] = ($item_row['numeric_current_qty'] * $row_link['current_quantity']) . ' ' . $row_link['UOM_Name'];
                    $row_link['Product_ID'] = $row_link['sub_product_id'];
                    $row_link['Name'] = $row_link['Product_Name'];
                    $row_link['link_product_class'] = '';
                    $row_link['TAG'] = '';
                    $row_link['tag_lines'] = '';
                    $row_link['Product_Net_Price'] = '--';
                    $row_link['Product_Total_Price'] = '--';
                    $row_link['Bar_Code'] = '--';
                    $row_link['link_product_class'] = '';
                    if (!empty($row_link['Printer_ID'])) {
                        $printer_array = explode(",", $row_link['Printer_ID']);
                        foreach ($printer_array as $printer_id) {
                            if ($is_deleted) {
                                $data['printers_linked'][$printer_id]['deleted'][] = $row_link;
                            } else {
                                $data['printers_linked'][$printer_id]['added'][] = $row_link;
                            }
                            if (!in_array($printer_id, $printers_id)) {
                                $printers_id[] = $printer_id;
                            }
                        }
                    }
                }
            }
        }
        $data['printer_ids'] = $printers_id;
        return $data;
    }
    public function einv_generate_tlv_qr_code($array_tag=array()){
        $index=1;
        $tlv_string='';
        foreach($array_tag as $tag_val){
            $tlv_string.=pack("H*", sprintf("%02X",(string) "$index")).
                         pack("H*", sprintf("%02X",strlen((string) "$tag_val"))).
                         (string) "$tag_val";
            $index++;                              
        }      
        return base64_encode($tlv_string);
    }
    public function posInvPOS($id, $data_arr = null) {
        if (empty($data_arr)) {
            $invoice_obj = new Invoice();
            $data_arr = $invoice_obj->getInvoiceToPrint($id);
        }
        //
        $organization = new organization();
        $getOrganizationDetails= $organization->getOrganizationDetails()[0];
        $data_arr['main']= array_merge($data_arr['main'],$getOrganizationDetails);
        $data_tlv= $this->einv_generate_tlv_qr_code(array($data_arr['main']['Organization_Name'],$data_arr['main']['org_vat_en'],str_replace(' ','T',$data_arr['main']['date_time']),$data_arr['main']['Invoice_Net_Total'],$data_arr['main']['vat1_total']));

        $data_arr['main']['qrcode'] = SITE_LINK . 'common_controller/GenerateQRCode?code=' . $data_tlv;

        if (!empty(smc_session()['default_setting']['pos_print_invoice_group_identical'])) {
            if (empty($invoice_obj))
                $invoice_obj = new Invoice();
            $data_arr = $invoice_obj->merge_identical_invoice_rows($data_arr);
        }
        
        $data_arr['main']['lebanon_vat'] = $data_arr['main']['Invoice_VAT'];
        $data_arr['main']['hide_lebanon_vat'] = 'hidden';
        $data_arr['main']['hide_usd_vat'] = 'hidden';
        if($data_arr['main']['Currency_Code'] == 'USD' ){
            $data_arr['main']['lebanon_vat'] = CommonFunctions::formatNumber( ((float)$data_arr['main']['Invoice_VAT']) * smc_session()['default_setting']['lebanon_vat_amount']);
            $data_arr['main']['hide_usd_vat'] = '';
        }else{
            $data_arr['main']['hide_lebanon_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]);
        $data_arr['main']['local_currency_rate'] = $exchange_rate_first_sec;
        $data_arr['main']['second_currency_rate'] = $exchange_rate_sec_first;


        if($data_arr['main']['Currency_Code'] == smc_session()['local_currency_code']){
            $data_arr['main']['total_second_currency_grand'] = CommonFunctions::formatNumber($data_arr['main']['grand_total_no_format'] * $data_arr['main']['local_currency_rate']).' ' .smc_session()['second_currency']['symbol'];
        }else{
            $data_arr['main']['total_second_currency_grand'] = CommonFunctions::formatNumber($data_arr['main']['grand_total_no_format'] * $data_arr['main']['second_currency_rate']).' ' .smc_session()['default_currency']['Currency_Symbol']; ;

        }
        $data_arr['main']['lebanon_vat_rate'] = smc_session()['default_setting']['lebanon_vat_amount'];

        //
        $data_arr['main']['type_preview'] = 'window.print()';
        $template_key = $data_arr['main']['is_actual'] ? ['act_pos_invoice', 'pos_invoice'] : 'pos_invoice';
        $template_row = Forms::build_print_template($template_key, $data_arr['main'], array('inv_detail' => $data_arr['Details'], 'inv_detail_linked' => $data_arr['DetailsLinked']
                    , 'disc' => $data_arr['disc_items'], 'disc_linked' => $data_arr['disc_items_linked']
                    , 'no_disc' => $data_arr['no_disc_items'], 'no_disc_linked' => $data_arr['no_disc_items_linked'])
        );
        $print_w_h = Forms::get_print_width_height('pos');
        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
        Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
    }

    public function posOrderPOS($data, $printer_id) {
        $printer_name = self::getprinterName($printer_id);
        if (empty($printer_name))
            return;
        $data['main']['printer_id_class' . $printer_id] = 'show_important';
        $data['main']['pos_order_main'] = '';
        $data['main']['pos_deleted_added_main'] = 'hidden';
        $inv_detail = empty($data['printers'][$printer_id]) ? array() : $data['printers'][$printer_id];
        $inv_detail_linked = empty($data['printers_linked'][$printer_id]) ? array() : $data['printers_linked'][$printer_id];
        //here we add settings if want for order to print linked or main product we need this since if we print main
        //and linked product is in another printer then it will print empty paper on the another printer..
        if (!empty(smc_session()['default_setting']['pos_order_link_product_printer']) && empty($inv_detail_linked))
            return;
        if (empty(smc_session()['default_setting']['pos_order_link_product_printer']) && empty($inv_detail))
            return;
        $template_key = $data['main']['is_actual'] ? ['act_pos_order', 'pos_order'] : 'pos_order';

        $template_row = Forms::build_print_template($template_key, $data['main'], array('inv_detail' => $inv_detail, 'inv_detail_linked' => $inv_detail_linked));
        $print_w_h = Forms::get_print_width_height('pos');
        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
        Forms::real_print($printer_name, $filename, ['repeat' => $template_row['copies']]);
    }

    public function viewInvoicePOS($id) {
        $invoice = new Invoice();
        $data_arr = $invoice->getInvoiceToPrint($id);
        $data_arr['main']['type_preview'] = 'window.print()';
        if (empty($this->info['is_posponed']))
            $template_key = $data_arr['main']['is_actual'] ? ['act_pos_invoice', 'pos_invoice'] : 'pos_invoice';
        else
            $template_key = $data_arr['main']['is_actual'] ? ['act_postponed_invoice', 'postponed_invoice', 'act_pos_invoice', 'pos_invoice'] : ['postponed_invoice', 'pos_invoice'];
        //        $print_template = empty($this->info['is_posponed']) ? 'view_invoice_pos' : ['postponed_invoice', 'view_invoice_pos'];
        $template_row = Forms::build_print_template($template_key, $data_arr['main'], array('inv_detail' => $data_arr['Details'], 'inv_detail_linked' => $data_arr['DetailsLinked']));
        return $template_row['html'];
    }

    public function posOrderRemovedAdded($data, $printer_id) {
        //        echo '<pre>';die(print_r($data));
        if ($printer_id === 'default')
            $printer_name = Forms::getDefaultprinterName();
        else
            $printer_name = self::getprinterName($printer_id);
        if (empty($printer_name))
            return;
        $data['main_invoice']['printer_id_class' . $printer_id] = 'show_important';
        $data['main_invoice']['pos_order_main'] = 'hidden';
        $data['main_invoice']['pos_deleted_added_main'] = '';
        $data['main_invoice']['added_class'] = empty($data['printers'][$printer_id]['added']) ? 'hidden' : '';
        $data['main_invoice']['deleted_class'] = empty($data['printers'][$printer_id]['deleted']) ? 'hidden' : '';
        $data['printers'][$printer_id]['added'] = !empty($data['printers'][$printer_id]['added']) ? $data['printers'][$printer_id]['added'] : array();
        $data['printers'][$printer_id]['deleted'] = !empty($data['printers'][$printer_id]['deleted']) ? $data['printers'][$printer_id]['deleted'] : array();
        $data['main_invoice']['added_class_linked'] = empty($data['printers_linked'][$printer_id]['added']) ? 'hidden' : '';
        $data['main_invoice']['deleted_class_linked'] = empty($data['printers_linked'][$printer_id]['deleted']) ? 'hidden' : '';
        $data['printers_linked'][$printer_id]['added'] = !empty($data['printers_linked'][$printer_id]['added']) ? $data['printers_linked'][$printer_id]['added'] : array();
        $data['printers_linked'][$printer_id]['deleted'] = !empty($data['printers_linked'][$printer_id]['deleted']) ? $data['printers_linked'][$printer_id]['deleted'] : array();
        //here we add settings if want for order to print linked or main product we need this since if we print main
        //and linked product is in another printer then it will print empty paper on the another printer..
        if (!empty(smc_session()['default_setting']['pos_order_link_product_printer']) && empty($data['printers_linked'][$printer_id]['added']) && empty($data['printers_linked'][$printer_id]['deleted']))
            return;
        if (empty(smc_session()['default_setting']['pos_order_link_product_printer']) && empty($data['printers'][$printer_id]['added']) && empty($data['printers'][$printer_id]['deleted']))
            return;
        $template_key = $data['main_invoice']['is_actual'] ? ['act_pos_order', 'pos_order', 'act_pos_deleted_added', 'pos_deleted_added'] : ['pos_order', 'pos_deleted_added'];
        //        echo"<pre>";die(print_r($data));
        $template_row = Forms::build_print_template($template_key, $data['main_invoice'], array(
                    'added_detail' => $data['printers'][$printer_id]['added'],
                    'added_detail_linked' => $data['printers_linked'][$printer_id]['added'],
                    'deleted_detail_linked' => $data['printers_linked'][$printer_id]['deleted'],
                    'deleted_detail' => $data['printers'][$printer_id]['deleted']));
        $print_w_h = Forms::get_print_width_height('pos');
        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
        Forms::real_print($printer_name, $filename, ['repeat' => $template_row['copies']]);
        //        
        //        $current_time = date("h:i:s a");
        //
        //        $prepare_time_lang = CommonLanguage::getMessage('time');
        //        $order_lang = CommonLanguage::getMessage('order');
        //        $table_number = CommonLanguage::getMessage('table_number');
        //        $notes = CommonLanguage::getMessage('note');
        //        $pdf->SetCreator(PDF_CREATOR);
        //        $pdf->SetTitle('Invoice');
        //        $pdf->setPrintHeader(false);
        //        $pdf->setPrintFooter(false);
        //        $pdf->SetMargins(0.1, 0.3, 0.1);
        //        //        if (@file_exists(dirname(__FILE__) . '/../TCPDF/examples/lang/ara.php')) {
        //        //            require(dirname(__FILE__) . '/../TCPDF/examples/lang/ara.php');
        //        //            $pdf->setLanguageArray($l);
        //        //        }
        //        $pdf->SetFont('aealarabiya', 'B', 12);
        //        $pdf->AddPage('', array(8, 22));
        //        $pdf->Cell(1.5, 1, '', 0, 0, 'l', false, '', 1);
        //        $pdf->Cell(4, 1, $prepare_time_lang . ' : ' . $current_time, 0, 0, 'C', false, '', 1);
        //        $pdf->Ln(0.5);
        //        $pdf->Cell(1.5, 1, '', 0, 0, 'l', false, '', 1);
        //        $pdf->Cell(4, 1, $order_lang . ' : ' . $data['main_invoice']['Bon_Number'], 0, 0, 'C', false, '', 1);
        //        $pdf->Ln(0.5);
        //        if ($data['main_invoice']['Inv_Type'] == 2) {
        //            $pdf->Cell(1.5, 1, '', 0, 0, 'l', false, '', 1);
        //            $pdf->Cell(4, 1, $table_number . ' : ' . $data['main_invoice']['table_name'], 0, 0, 'C', false, '', 1);
        //        }
        //
        //        //        $pdf->Ln(0.5);
        //
        //        $pdf->Ln();
        //        $w = array(5.5, 1.5);
        //        $header = array(CommonLanguage::getMessage('Name'), CommonLanguage::getMessage('qty'));
        //        $num_headers = count($header);
        //        //        echo '<pre>';
        //        //        print_r($data['printers'][$printer]);
        //
        //        if (!empty($data['printers'][$printer]['added'])) {
        //            $pdf->Cell(1.5, 0.2, '', 0, 0, 'l', false, '', 1);
        //            $pdf->Cell(4, 1, 'Added', array('dash' => 0), 0, 'C', false, '', 1);
        //            $pdf->Ln();
        //            $pdf->Ln(0.2);
        //
        //            $pdf->SetFillColor(255, 255, 255);
        //            $pdf->SetTextColor(0);
        //            $pdf->SetDrawColor(0, 0, 0);
        //
        //
        //            for ($i = 0; $i < $num_headers; ++$i) {
        //                $pdf->Cell($w[$i], 0.5, $header[$i], 0, 0, 'l');
        //            }
        //            $pdf->Ln();
        //            $pdf->Cell(7, 0, '', 'T');
        //            $pdf->Ln(0.1);
        //            $pdf->SetFillColor(255, 255, 255);
        //            $pdf->SetTextColor(0);
        //            $pdf->SetFont('aealarabiya', '', 9);
        //            //            echo '<pre>';
        //
        //            foreach ($data['printers'][$printer]['added'] as $row) {
        //                $name = $row['Name'];
        //                if ($row['UOM_Name'] != '-') {
        //                    $name.= " ({$row['UOM_Name']})";
        //                }
        //                $pdf->MultiCell($w[0], 0, $name, 0, 'L', false, 0, '', '', true, 0, false, 0.1);
        //                $quantity = substr($row['Item_Quantity_Current'], 0, -1);
        //                $pdf->MultiCell($w[1], 0, $quantity, 0, 'L', false, 1, '', '', true, 0, false, 0.1);
        //
        //                if ($row['TAG'] != '') {
        //                    $pdf->Ln(0.4);
        //                    $pdf->Cell(0.3, 0.1, '', 0, 0, 'l', false, '', 1);
        //                    $pdf->MultiCell(6, 0, $row['TAG'], 0, 'R', false, 1, '', '', true);
        //                }
        //                //            $pdf->Cell(7, 0, '', 'T');
        //                $pdf->Ln();
        //                $pdf->Ln(0.1);
        //            }
        //        }
        //        if (!empty($data['printers'][$printer]['deleted'])) {
        //            //        $pdf->Cell(7, 0, '', 'T');
        //            //        $pdf->Ln(0.5);
        //            $pdf->SetFont('aealarabiya', 'B', 12);
        //            $pdf->Cell(1.5, 0.2, '', 0, 0, 'l', false, '', 1);
        //            $pdf->Cell(4, 1, 'Deleted', array('LTRB' => array('dash' => 0)), 0, 'C', false, '', 1);
        //            $pdf->Ln();
        //            $pdf->SetFillColor(255, 255, 255);
        //            $pdf->SetTextColor(0);
        //            $pdf->SetDrawColor(0, 0, 0);
        //
        //            for ($i = 0; $i < $num_headers; ++$i) {
        //                $pdf->Cell($w[$i], 0.5, $header[$i], 0, 0, 'l');
        //            }
        //            $pdf->Ln();
        //            $pdf->Cell(7, 0, '', 'T');
        //            $pdf->Ln(0.1);
        //            $pdf->SetFillColor(255, 255, 255);
        //            $pdf->SetTextColor(0);
        //            $pdf->SetFont('aealarabiya', '', 9);
        //            foreach ($data['printers'][$printer]['deleted'] as $row) {
        //                $name = $row['Name'];
        //                if ($row['UOM_Name'] != '-') {
        //                    $name.= " ({$row['UOM_Name']})";
        //                }
        //                $pdf->MultiCell($w[0], 0, $name, 0, 'L', false, 0, '', '', true, 0, false, 0.1);
        //                $pdf->MultiCell($w[1], 0, $row['Item_Quantity_Current'], 0, 'L', false, 1, '', '', true, 0, false, 0.1);
        //
        //                if ($row['TAG'] != '') {
        //                    $pdf->Ln(0.4);
        //                    $pdf->Cell(0.3, 0.1, '', 0, 0, 'l', false, '', 1);
        //                    $pdf->MultiCell(6, 0, $row['TAG'], 0, 'R', false, 1, '', '', true);
        //                }
        //                $pdf->Ln();
        //                $pdf->Ln(0.2);
        //            }
        //        }
        //        $pdf->Ln();
        //
        //        $pdf->Cell(7, 0, '', 'T');
        //        $pdf->Ln(0.1);
        //        if ($data['main_invoice']['Invoice_Description'] != "") {
        //            $pdf->SetFont('aealarabiya', '', 9);
        //            $pdf->MultiCell(7, 0, $notes . ' : ' . $data['main_invoice']['Invoice_Description'], 0, 'L', false, 1, '', '', true, 0, false, 0.1);
        //        }
        //        $pdf->Output(dirname(dirname(__DIR__)) . '/' . $filename . '.pdf', 'F');
    }

    //    public function printPosPayment($data) {
    //        $template_row = Forms::build_print_template('pos_payment', $data);
    //        $print_w_h = Forms::get_print_width_height('pos');
    //        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
    //        Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
    //    }
    //
    //    public function printPosDeposit($data) {
    //        $template_row = Forms::build_print_template('pos_deposite', $data);
    //        $print_w_h = Forms::get_print_width_height('pos');
    //        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
    //        Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
    //    }
    //
    //    public function printPosWithDraw($data) {
    //        $template_row = Forms::build_print_template('pos_withdrawal', $data);
    //        $print_w_h = Forms::get_print_width_height('pos');
    //        $filename = Forms::html2pdf($template_row['html'], $print_w_h);
    //        Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
    //        //        $current_time = date("Y-m-d h:i:s a");
    //        //        $time_lang = CommonLanguage::getMessage('print_time');
    //        //        $pdf = new tcpdf('P', 'cm', array(8, 22), true, 'UTF-8', true);
    //        //        $pdf->SetCreator(PDF_CREATOR);
    //        //        $pdf->SetTitle('WithDraw');
    //        //        $pdf->setPrintHeader(false);
    //        //        $pdf->setPrintFooter(false);
    //        //        $pdf->SetMargins(0.3, 0.3, 0.3);
    //        //        if (@file_exists(dirname(__FILE__) . '/../TCPDF/examples/lang/ara.php')) {
    //        //            require(dirname(__FILE__) . '/../TCPDF/examples/lang/ara.php');
    //        //            $pdf->setLanguageArray($l);
    //        //        }
    //        //        $pdf->SetFont('aealarabiya', '', 14);
    //        //        $pdf->AddPage('', array(8, 22));
    //        //        $html = '
    //        ////
    //        ////<style>
    //        ////  table.first {
    //        ////        color: #000;
    //        ////        font-family: aealarabiya;
    //        ////        font-size: 15pt;
    //        ////       text-align:center
    //        ////    }
    //        ////   th{
    //        ////        border-bottom: 1px solid #000;  
    //        ////        text-align:center;
    //        ////        font-size:14pt;
    //        ////   }
    //        ////
    //        ////</style>
    //        ////<body>
    //        ////
    //        ////
    //        ////
    //        ////    <table class="first">
    //        ////        <thead><tr><td colspan="4">' . CommonLanguage::getMessage('withdrawal') . '</td></tr>
    //        ////        <tr><td colspan="4">' . $time_lang . '</td></tr>
    //        ////        <tr><td colspan="4">' . $current_time . '</td></tr>
    //        ////        <tr>
    //        ////            <th style="width:50%">' . CommonLanguage::getMessage('Name') . '</th>
    //        ////            <th style="width:50%">' . CommonLanguage::getMessage('total') . '</th>
    //        ////
    //        ////        </tr>
    //        ////        </thead>
    //        ////        <tbody>
    //        ////        <tr>
    //        ////        <td style="width:50%">' . smc_session()['user_logged_username'] . '</td><td style="width:50%">' . number_Xformat($data[0]) . ' ' . $data[1] . '</td>
    //        ////
    //        ////       </tr></tbody> </table><hr></body>';
    //        //        $pdf->writeHTML($html, true, false, true, false, '');
    //        //        $filename = 'WithDraw' . (time() + rand());
    //        //        $pdf->Output(dirname(dirname(__DIR__)) . '/' . $filename . '.pdf', 'F');
    //        //        Forms::real_print(null, $filename);
    //    }

    public function generateInvoice($inv_id) {
        $data = array();
        $this->db->query('START TRANSACTION');
        $invoice_data = CommonFunctions::CommonView('tbl_invoices', ['Invoice_ID_Auto'], [$inv_id])[0];
        if ($invoice_data['Is_Closed'] == 1)
            return ['error'];
        $data['Customer_ID'] = 0;
        $data['Invoice_Net_Total'] = $invoice_data['Invoice_Net_Total'];
        $data['Invoice_VAT'] = $invoice_data['Invoice_VAT'];
        $data['vat1_total'] = $invoice_data['vat1_total'];
        $data['vat2_total'] = $invoice_data['vat2_total'];
        $data['invoice_nb'] = $invoice_data['Invoice_ID'];
        $data['Invoice_Currency'] = $invoice_data['Invoice_Currency'];
        $data['Logged_ID'] = $invoice_data['Logged_ID'];
        $data['rate'] = $invoice_data['current_rate'];
        $data['Invoice_ID_Auto'] = $inv_id;
        $data['main_nb'] = $invoice_data['Invoice_ID'];
        $data['prefix'] = $invoice_data['invoice_prefix'];
        $data['cash_amount'] = $invoice_data['Invoice_Net_Total'] + $invoice_data['Invoice_Shipping'] + $invoice_data['service_value'];
        $data['other_amount'] = 0;
        $data['check_credit'] = '';
        $data['service_value'] = $invoice_data['service_value'];
        $data['invoice_type'] = 2;
        $data['is_edited_invoice'] = 1;
        $data['pending_status'] = 2;
        $data['Is_Delivery'] = $invoice_data['Is_Delivery'];
        $sales_account = smc_session()['user_accounts']['sales_account_id'];
        $prod_ids_arr = array();
        $invoice_details_query = $this->db->query('select * from tbl_invoice_products_details where Invoice_ID_Auto = "' . $inv_id . '"');
        while ($item = $this->db->assoc($invoice_details_query)) {
            $prod_ids_arr[] = $item['Product_ID'];
            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => $item['Product_Total_Price'],
                "description" => '', "vat_amount" => ($item['vat_amount'] + $item['vat2_amount']));
        }
        $prod_str = implode( ',',$prod_ids_arr);
        $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $sales_account, $invoice_data['Invoice_Discount'], smc_session()['user_accounts']['sales_ship_account_id'], $invoice_data['Invoice_Shipping'], $invoice_data['tax_amount']);
        $return_data = $this->setdata($data)->payInvoice($prod_trans_arr);
        return $return_data;
        //        $error = $this->db->error();
        //
        //        echo '<pre>';
        //        echo $return_data;
        //        print_r($data);
        //        die('ok');
    }

    public function generateCashInvoice($inv_id) {
        $data = array();
        $data['with_print'] = $this->info['with_print'];
        $this->db->query('START TRANSACTION');
        $invoice_data = CommonFunctions::CommonView('invoice_list_main', ['Invoice_ID_Auto'], [$inv_id])[0];
        //        if ($invoice_data['Is_Closed'] == 1)
        //            return ['error'];
        $data['Customer_ID'] = $invoice_data['Customer_ID'];
        $data['is_actual'] = $invoice_data['is_actual'];
        $data['Invoice_Net_Total'] = $invoice_data['Invoice_Net_Total'];
        $data['Invoice_VAT'] = $invoice_data['Invoice_VAT'];
        $data['vat1_total'] = $invoice_data['vat1_total'];
        $data['vat2_total'] = $invoice_data['vat2_total'];
        $data['invoice_nb'] = $invoice_data['Invoice_ID'];
        $data['Invoice_Date'] = $invoice_data['Invoice_Date'];
        $data['Invoice_Due_Date'] = $invoice_data['Invoice_Due_Date'];
        $data['Invoice_Currency'] = $invoice_data['Invoice_Currency'];
        $data['Logged_ID'] = $invoice_data['Logged_ID'];
        $data['date_created'] = $invoice_data['date_created'];
        $data['created_logged_id'] = $invoice_data['created_logged_id'];
        $data['rate'] = $invoice_data['current_rate'];
        $data['second_rate'] = $invoice_data['second_currency_rate'];
        $data['Invoice_ID_Auto'] = $inv_id;
        $data['main_nb'] = $invoice_data['Invoice_ID'];
        $data['prefix'] = $invoice_data['invoice_prefix'];
        $data['cash_amount'] = $invoice_data['Invoice_Net_Total'] + $invoice_data['Invoice_Shipping'] + $invoice_data['service_value'];
        $data['other_amount'] = 0;
        $data['check_credit'] = '';
        $data['service_value'] = $invoice_data['service_value'];
        $data['currency_round'] = $invoice_data['currency_round'];
        $data['is_edited_invoice'] = 1;
        $data['open_cash_table'] = 0;
        $data['invoice_type'] = $invoice_data['invoice_type'];
        $data['pending_status'] = 2;
        $sales_account = smc_session()['user_accounts']['sales_account_id'];
        $prod_ids_arr = array();
        $invoice_details_query = $this->db->query('select * from tbl_invoice_products_details where Invoice_ID_Auto = "' . $inv_id . '"');
        while ($item = $this->db->assoc($invoice_details_query)) {
            $prod_ids_arr[] = $item['Product_ID'];
            $prod_arr[] = array("product_id" => $item['Product_ID'],
                "total_amount" => $item['Product_Total_Price'],
                "description" => '', "vat_amount" => ($item['vat_amount'] + $item['vat2_amount']));
        }
        $prod_str = implode( ',',$prod_ids_arr);
        $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'inv', $sales_account, $invoice_data['Invoice_Discount'], smc_session()['user_accounts']['sales_ship_account_id'], $invoice_data['Invoice_Shipping'], $invoice_data['tax_amount']);
        $date_time = date('Y-m-d H:i:s');
        $this->db->prepare_Stmt('UPDATE tbl_invoices  SET Invoice_Paid_Amount = ?, Account_ID = ?
                                        ' . ($data['invoice_type'] == 3 ? ',invoice_type = 1' : '') .
                (($data['invoice_type'] == 3 || $data['invoice_type'] == 2 ) ? ',Invoice_Status = 2' : '') . ',
                    date_time=?,is_main_transfer=0 WHERE Invoice_ID_Auto = ? 
                        ', [&$data['cash_amount'], &$sales_account, $date_time, &$data['Invoice_ID_Auto']]);
        $data['invoice_type'] = 2;
        $data['is_printed_before'] = $invoice_data['is_printed'];
        //if user press generate cash multi times or.. delete previous transactions
        $jv = '';
        $jv_query = $this->db->query("SELECT DISTINCT JV_ID,Current_Ex_Rate,Transaction_Date 
            FROM tbl_accounting_transactions WHERE main_id='" . $inv_id . "' AND main_type= 'inv' ");
        $jv_assoc = $this->db->assoc($jv_query);
        if (count($jv_assoc) > 0) {
            $jv = $jv_assoc['JV_ID'];
            $this->db->prepare_Stmt("DELETE FROM tbl_accounting_transactions  WHERE main_id= ? AND main_type= 'inv' ", [&$inv_id]);
        }
        $arr = ['type' => 'inv', 'main_id' => $inv_id, 'action' => 1, 'date_time' => $date_time,
            'user_id' => $data['Logged_ID']];
        CommonFunctions::add_user_log($arr);
        //on payinvoice function already end transaction or roolback
        return $this->setdata($data)->payInvoice($prod_trans_arr, $jv);
    }

    public function payInvoice($prod_trans_arr, $jv = '') {


        $is_actual = $this->info['is_actual'];
        $today = Date::getToday();
        //die('heree');


        $sales_account = smc_session()['user_accounts']['sales_account_id'];
        $cash_account = smc_session()['user_accounts']['cash_account_id'];
        $other_account = smc_session()['user_accounts']['other_account_id'];
        $shipping_account = smc_session()['user_accounts']['sales_ship_account_id'];
        $service_account = smc_session()['account_setting']['service_account_id'];


        $second_curr_cash_account  = smc_session()['account_setting']['second_curr_cash_account'];
        $second_cash_cat_amount = $this->info['second_cash_cat_amount'];

        $first_currency = $this->info['first_currency'];
        $second_currency = $this->info['second_currency'];
        $exchange_rate_first_sec_arr = CurrencyFactory::returnExchangeRate($first_currency,$second_currency);
        $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($second_currency,$first_currency);
        $exchange_rate_sec_first = $exchange_rate_sec_first_arr[1] == '*' ? $exchange_rate_sec_first_arr[0] : (1 / $exchange_rate_sec_first_arr[0]);

        $second_cash_cat_amount_local_1 = $second_cash_cat_amount * $exchange_rate_first_sec;
        $second_cash_cat_amount_local_2 = $second_cash_cat_amount * $exchange_rate_sec_first;


        if($second_currency == smc_session()['local_currency']){
            $exchange_rate_sec_first = 1;
            $second_cash_cat_amount_local_2 = $second_cash_cat_amount;
            $second_curr_cash_account = $cash_account;
            $cash_account = smc_session()['account_setting']['second_curr_cash_account'];
        }


        if (empty($jv))
            $jv = JV::returnJV($is_actual);
        $desc = "Invoice from pos";



        $customer_account = self::getCustomerAccount($this->info['Customer_ID']);
        $customerAccount = $customer_account['Account_ID'];
        //        $customerAccount = array_key_exists('account_customer_id', $this->info) ? $this->info['account_customer_id'] : "4111";

        $customer_vat = Customer::returnCustomerVATAccount($this->info['Customer_ID'])['Account_ID'];
        $vat_account = $customer_vat;
        $amount_novat = $this->info['Invoice_Net_Total'] - $this->info['Invoice_VAT'];
        $ref_num = "Inv." . $this->info['invoice_nb'];
        $pos_customer_id = !empty($this->info['pos_customer_id']) ? $this->info['pos_customer_id'] : 0;
        $this->info['salesman_id'] = !empty($this->info['salesman_id']) ? $this->info['salesman_id'] : 0;

        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" => $this->info['Invoice_Date'],
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $this->info['date_created'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => (empty($trans_main['trans_desc']) ? $desc : $trans_main['trans_desc']),
                    "Current_Ex_Rate" => $this->info['rate'],
                    "second_currency_rate" => $this->info['second_rate'],
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "main_nb" => $this->info['main_nb'],
                    "prefix" => $this->info['prefix'],
                    "subtype" => 'inv',
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "salesman_id" => $this->info['salesman_id']
                ];
                JV::addTransaction($data_trans, $is_actual);
            }


            if (isset($trans['person'])) {
                $pos_customer_id = !empty($this->info['pos_customer_id']) ? $this->info['pos_customer_id'] : 0;
                $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'];
                //              echo $cust_amount.'===';
                //                die();
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref_num,
                    "Transaction_Account" => $customerAccount,
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $cust_amount,
                    "Transaction_Date" => $this->info['Invoice_Date'],
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "date_created" => $this->info['date_created'],
                    "created_logged_id" => $this->info['created_logged_id'],
                    "Transaction_Description" => (empty($trans_person['trans_desc']) ? $desc : $trans_person['trans_desc']),
                    "Current_Ex_Rate" => $this->info['rate'],
                    "second_currency_rate" => $this->info['second_rate'],
                    "main_id" => $this->info['Invoice_ID_Auto'],
                    "main_type" => "inv",
                    "main_nb" => $this->info['main_nb'],
                    "prefix" => $this->info['prefix'],
                    "due_date" => $this->info['Invoice_Due_Date'],
                    "pos_customer_id" => $pos_customer_id,
                    "salesman_id" => $this->info['salesman_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" => $this->info['Invoice_Date'],
                "Currency_ID" => $this->info['Invoice_Currency'],
                "Logged_ID" => $this->info['Logged_ID'],
                "date_created" => $this->info['date_created'],
                "created_logged_id" => $this->info['created_logged_id'],
                "Transaction_Description" => (empty($trans_person['trans_desc']) ? $desc : $trans_person['trans_desc']),
                "Current_Ex_Rate" => $this->info['rate'],
                "second_currency_rate" => $this->info['second_rate'],
                "main_id" => $this->info['Invoice_ID_Auto'],
                "main_type" => "inv",
                "main_nb" => $this->info['main_nb'],
                "prefix" => $this->info['prefix'],
                "due_date" => $this->info['Invoice_Due_Date'],
                "pos_customer_id" => $pos_customer_id,
                "salesman_id" => $this->info['salesman_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_trans = ["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" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => (empty($trans_person['trans_desc']) ? $desc : $trans_person['trans_desc']),
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($data_trans, $is_actual);
        //sales amount - vat amount for sales account
            //        $dat_2 = ["JV_ID" => $jv,
            //            "Transaction_Reference" => 'inv',
            //            "Transaction_Account" => $sales_account,
            //            "Transaction_Type" => "Credit",
            //            "Transaction_Amount" => $amount_novat,
            //            "Transaction_Date" => $today,
            //            "Currency_ID" => $this->info['Invoice_Currency'],
            //            "Logged_ID" => $this->info['Logged_ID'],
            //            "Transaction_Description" => $desc,
            //            "Current_Ex_Rate" => $this->info['rate'],
            //            "main_id" => $this->info['Invoice_ID_Auto'],
            //            "main_type" => "inv"
            //        ];
            //        JV::addTransaction($dat_2);
            //        $error = $this->db->error();
            //        die(print_r($dat_2));
            //        $error = $this->db->error();
            //        die(print_r($dat_2));
            //vat   
            $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" => $this->info['Invoice_Date'],
            "Currency_ID" =>  $Invoice_Currency,
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $second_rate2,
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "sub_type" => "vat1",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        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" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_3, $is_actual);
        //$error = $this->db->error();
            //        die(print_r($error));
            //customer transaction in case on credit amount
            //        $dat_6 = ["JV_ID" => $jv,
            //            "Transaction_Reference" => $ref_num,
            //            "Transaction_Account" => $customerAccount,
            //            "Transaction_Type" => "Debit",
            //            "Transaction_Amount" => $this->info['invoice_unpaid_amount'],
            //            "Transaction_Date" => $today,
            //            "Currency_ID" => $this->info['Invoice_Currency'],
            //            "Logged_ID" => $this->info['Logged_ID'],
            //            "Transaction_Description" => $desc,
            //            "Current_Ex_Rate" => "0",
            //            "main_id" => $this->info['Invoice_ID_Auto'],
            //            "main_type" => "inv"
            //        ];
            //        JV::addTransaction($dat_6);
            //        $dat_6 = ["JV_ID" => $jv,
            //            "Transaction_Reference" => $ref_num,
            //            "Transaction_Account" => $customerAccount,
            //            "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'],
            //            "Transaction_Description" => $desc,
            //            "Current_Ex_Rate" => $this->info['rate'],
            //            "main_id" => $this->info['Invoice_ID_Auto'],
            //            "main_type" => "inv"
            //        ];
            //        JV::addTransaction($dat_6);
            //        $error = $this->db->error();
            //        die(print_r($error));
        $dat_6 = ["JV_ID" => $jv,
            "Transaction_Reference" => $ref_num,
            "Transaction_Account" => $customerAccount,
            "Transaction_Type" => "Credit",
            "Transaction_Amount" => ($this->info['cash_amount'] + $this->info['other_amount'] + $second_cash_cat_amount_local_2),
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "due_date" => $this->info['Invoice_Due_Date'],
            "pos_customer_id" => $pos_customer_id,
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_6, $is_actual);
        //cash transaction
        $dat_4 = ["JV_ID" => $jv,
            "Transaction_Reference" => 'cash',
            "Transaction_Account" => $cash_account,
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $this->info['cash_amount'],
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "subtype" => 'cash',
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_4, $is_actual);

        //transaction for other type payment
        $dat_5 = ["JV_ID" => $jv,
            "Transaction_Reference" => $this->info['check_credit'] == 2 ? 'credit' : 'check',
            "Transaction_Account" => $other_account,
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $this->info['other_amount'],
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => !empty($this->info['other_description']) ? $this->info['other_description'] : $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "subtype" => $this->info['check_credit'] == 2 ? 'credit' : 'check',
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_5, $is_actual);

        //transaction for second_curr_cash_account type payment
        $dat_10 = ["JV_ID" => $jv,
            "Transaction_Reference" =>  'cash',
            "Transaction_Account" => $second_curr_cash_account, 
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $second_cash_cat_amount,
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $second_currency,
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => !empty($this->info['other_description']) ? $this->info['other_description'] : $desc,
            "Current_Ex_Rate" => $exchange_rate_sec_first,
            "second_currency_rate" => 1,
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "subtype" => 'cash',
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_10, $is_actual);
    

        //transaction for shipping 
            //        $dat_7 = ["JV_ID" => $jv,
            //                  "Transaction_Reference" => 'ship',
            //                  "Transaction_Account" => $shipping_account,
            //                  "Transaction_Type" => "Credit",
            //                  "Transaction_Amount" => $this->info['Invoice_Shipping'],
            //                  "Transaction_Date" => $today,
            //                  "Currency_ID" => $this->info['Invoice_Currency'],
            //                  "Logged_ID" => $this->info['Logged_ID'],
            //                  "Transaction_Description" => $desc,
            //                  "Current_Ex_Rate" => $this->info['rate'],
            //                  "main_id" => $this->info['Invoice_ID_Auto'],
            //                  "main_type" => "inv",
            //                  "main_nb" => $this->info['main_nb'],
            //                  "prefix" => $this->info['prefix'],
            //                  "subtype" => 'ship',
            //                  "due_date" => $today
            //                 ];
            //        JV::addTransaction($dat_7, $is_actual);

        $dat_8 = ["JV_ID" => $jv,
            "Transaction_Reference" => $ref_num,
            "Transaction_Account" => $customerAccount,
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $this->info['service_value'],
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "subtype" => 'service',
            "due_date" => $this->info['Invoice_Due_Date'],
            "pos_customer_id" => $pos_customer_id,
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_8, $is_actual);

        // service if exist 
        $dat_9 = ["JV_ID" => $jv,
            "Transaction_Reference" => 'service',
            "Transaction_Account" => $service_account,
            "Transaction_Type" => "Credit",
            "Transaction_Amount" => $this->info['service_value'],
            "Transaction_Date" => $this->info['Invoice_Date'],
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info['Logged_ID'],
            "date_created" => $this->info['date_created'],
            "created_logged_id" => $this->info['created_logged_id'],
            "Transaction_Description" => $desc,
            "Current_Ex_Rate" => $this->info['rate'],
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $this->info['Invoice_ID_Auto'],
            "main_type" => "inv",
            "main_nb" => $this->info['main_nb'],
            "prefix" => $this->info['prefix'],
            "subtype" => 'service',
            "due_date" => $this->info['Invoice_Due_Date'],
            "salesman_id" => $this->info['salesman_id']
        ];
        JV::addTransaction($dat_9, $is_actual);


        //to close invoices for related tables
        $q_r = $this->db->query('SELECT Related_Tables FROM tbl_invoices where Invoice_ID_Auto ="' . $this->info['Invoice_ID_Auto'] . '"');
        $related_tables = $this->db->assoc($q_r)['Related_Tables'];
        if (!empty($related_tables)) {
            //            $cond = 'or table_id in (' . $related_tables . ')';
            $this->db->query('UPDATE tbl_invoices 
                                    SET
                                        Is_Closed = 1,
                                        is_committed = 1,is_main_transfer = 0
                                        ' . ($this->info['with_print'] == 1 ? ',is_printed_invoice = 1' : '') . '
                                    WHERE 
                                        table_id in (' . $related_tables . ')
                                    and 
                                        Is_Closed = 0
                        ');
        }
        $this->db->prepare_Stmt('UPDATE tbl_invoices 
                                    SET
                                        Is_Closed = 1,
                                        is_committed = 1,is_main_transfer = 0
                                        ' . ($this->info['with_print'] == 1 ? ',is_printed_invoice = 1' : '') . '
                                    WHERE 
                                        Invoice_ID_Auto = ? 
                                    and
                                        Is_Closed = 0
                        ', [&$this->info['Invoice_ID_Auto']]);

        $error = $this->db->error();
        if (empty($error)) {
            //            if ($this->info['invoice_type'] == 2 || (smc_session()['default_setting']['activate_smart_diner'] == 1 && $this->info['invoice_type'] == 1)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query("COMMIT");
            //
            if (smc_session()['default_setting']['sumatra_print'] == 1 && !$this->stop_transaction_start_end)
                self::printPOSInvoice($this->info['Invoice_ID_Auto'], $this->info['invoice_type']);
            else
                return $this->info['Invoice_ID_Auto'];
            //            }
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query("ROLLBACK");
            return $error;
        }
        //        return array_unique($error);
    }

    //    public function returnCustomerVATAccount($cust_code) {
    //        //        echo $cust_code;
    //        //        die();
    //        $acc_last_digits = substr($cust_code, 4, 4);
    //        $query = $this->db->query('SELECT 
    //                                        Account_Code
    //                                    FROM 
    //                                        tbl_chart_of_accounts
    //                                    WHERE 
    //                                        LEFT(Account_Code,4) = "4427"
    //                                    AND 
    //                                        RIGHT(Account_Code,4) = "' . $acc_last_digits . '"
    //                ');
    //        $row = $this->db->assoc($query);
    //        return $row['Account_Code'];
    //    }

    public function getOrganizationAddress() {
        $data = array();
        $query = $this->db->query('SELECT
                                       o.Organization_Name,
                                        o.Organization_Phone,
                                        o.Organization_Commercial_Registry,
										CONCAT(ct.Name,", ",p.Organization_Street) AS Org_Address

                                    FROM
                                        tbl_organization o

                                    LEFT JOIN
                                        tbl_organization_postal_address p
                                    ON
                                        p.Organization_ID = o.Organization_ID

                                    LEFT JOIN
                                        tbl_all_cities ct
                                    ON
                                        p.Organization_City = ct.ID


                ');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function posReturn() {
        $this->ware_house_depot->stop_transaction_start_end = true;
        $is_actual = !isset($this->info['is_actual']) ? 0 : $this->info['is_actual'];
        $mydate = date("Y-m-d H:i:s");
        $today = Date::getToday();
        $check = CommonFunctions::check_lock_data(['type' => 'return', 'start_date' => $today, 'is_actual' => $is_actual]);

//        $check = JV::checkCurrentYear($today, $today, 0);
//        echo $check.'===';die();
        if ($check !== '') {
            $error = array();
            $error[0] = $check;
            return $error;
        }
        $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);
        $this->info['Is_Customer_Invoice'] = 1;
        $paid = $this->info['cash_amount'] + $this->info['other_amount'];
        $rem = $this->info['invoice_unpaid_amount'];
        $amount_novat = $this->info['Invoice_Net_Total'] - $this->info['Invoice_VAT'];


        $customer_account = self::getCustomerAccount($this->info['Customer_ID']);
        $account_credit = $customer_account['Account_ID'];

        //        $customer_vat = Customer::returnCustomerVATAccount($customer_account['Account_Code'])['Account_ID'];
        //        $account_credit = self::getCustomerAccount($this->info['Customer_ID']);
        $vat_account = Customer::returnCustomerVATAccount($this->info['Customer_ID'])['Account_ID'];
        $account_debit = smc_session()['user_accounts']['sales_account_id'];
        $credit_amount = $rem;
        $debit_amount = $amount_novat;
        $operation = "+";
        $payment_type = "Credit";
        $tax_type = "Debit";
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $inv_id = NULL;
        $depot_id = smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'];
        $rate = CurrencyFactory::getLastExRate($this->info['Invoice_Currency']);
        $this->info['second_rate'] = CurrencyFactory::getSecondCurrencyLastExRate($this->info['Invoice_Currency']);

        $this->info['branch_id'] = CommonBusiness::getBranchByDepot($depot_id);
        $ret_num_arr = self::getMaxReturn($this->info['branch_id']);
        $prefix = $ret_num_arr['prefix'];
        $ret_num = $ret_num_arr['inv_nb'];
        $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;


        $data = [
            &$ret_num,
            &$prefix,
            &$inv_id,
            &$this->info['Invoice_Sub_Total'],
            &$this->info['Invoice_Net_Total'],
            &$this->info['Invoice_VAT'],
            &$this->info['vat1_total'],
            &$this->info['vat2_total'],
            &$paid,
            &$today,
            &$this->info['Is_Customer_Invoice'],
            &$this->info['Invoice_Currency'],
            &$this->info['Customer_ID'],
            &$this->info['Discount_Amount'],
            &$this->info['Invoice_Discount'],
            &$this->info['Logged_ID'],
            &$this->info['Logged_ID'],
            &$this->info['tax_amount'],
            &$depot_id,
            &$mydate,
            &$mydate,
            &$rate,
            &$this->info['second_rate'],
            &$this->year_id,
            &$this->info['branch_id'],
            &$this->info['Class_ID'],
            &$sales_id,
            &$account_debit,
            &$is_actual
        ];
        $this->db->prepare_Stmt("
                                    INSERT
                                    INTO
                                        tbl_accounting_return_invoices
                                    (
                                        Return_ID,
                                        invoice_prefix,
                                        Invoice_Purchase_ID,
                                        Return_Invoice_Total,
                                        Return_Net_Total,Invoice_VAT,vat1_total,vat2_total,
                                        Return_Paid_Total,
                                        Return_Invoice_Date,
                                        Is_Customer_Invoice,
                                        Currency_ID,
                                        Person_ID,
                                        discount_amount,
                                        discount_percent,
                                        Logged_ID,created_logged_id,
                                        tax_amount,
                                        Depot_ID,
                                        date_time,date_created,
                                        current_rate,second_currency_rate,
                                        current_year_id,
                                        branch_id,Class_ID,
                                        Sales_ID,
                                        Account_ID,Is_Actual
                                    )
                                        VALUES
                                    (
                                        ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
                                    )
                                ", $data);


        $return_id = $this->db->id();
        if (!empty($this->info['is_return_postponed']) && !empty($this->info['Invoice_ID_Auto'])) {
            $this->db->prepare_Stmt('update tbl_invoices set posponted_type = 6 where Invoice_ID_Auto=?', [$this->info['Invoice_ID_Auto']]);
        }
        $main_type = 'rin';
        //        $depot_id = smc_session()['default_depot_id'];
        $prod_arr = array();
        $prod_ids_arr = array();
        $damaged_array = array();
        foreach ($this->info['products'] as $items) {
            $item["vat2_percent"] = !empty($item["vat2_percent"]) ? $item["vat2_percent"] : 0;
            $item["vat2_amount"] = !empty($item["vat2_amount"]) ? $item["vat2_amount"] : 0;
            $items['expiry_date'] = !empty($items['expiry_date']) ? $items['expiry_date'] : NULL;
            $lot_nb = !empty($items['lot_nb']) ? $items['lot_nb'] : '';
            $serial_nb = !empty($items['serial_nb']) ? $items['serial_nb'] : '';
            $is_service = !empty($items['is_service']) ? $items['is_service'] : 0;
            $is_damaged = empty($items['is_damaged']) ? 0 : 1;
            $prod_ids_arr[] = $items['Product_ID'];
            //            $quantity = Product::getConvertedQuantity($items['UOM_ID'], $items['Product_Quantity'], $items['Product_ID']);
            $ProductQuantityRate = Product::getConvertedQuantity($items['UOM_ID'], 1, $items['Product_ID']);
            $quantity = $ProductQuantityRate * $items['Product_Quantity'];
            $Product_Total_Price = $items["Return_Product_Total"]; // - $items['vat_amount'] - $items["vat2_amount"];
            $prod_arr[] = array("product_id" => $items['Product_ID'],
                "total_amount" => ($Product_Total_Price),
                "description" => '', "vat_amount" => ($items['vat_amount'] + $items['vat2_amount']));



            $costdata = [
                "Product_ID" => $items['Product_ID'],
                "Quantity" => $quantity,
                "Unit_Cost" => '',
                "unit_price" => $items['Net_Price'],
                "Currency_ID" => $this->info['Invoice_Currency'],
                "date_time" => $mydate,
                "current_rate" => $rate,
                "depot_id" => $depot_id,
                "trans_date" => $today,
                "current_quantity" => $items["Product_Quantity"],
                "uom_id" => $items['UOM_ID'],
                "is_actual" => $is_actual,
                "expiry_date" => $items['expiry_date'],
                "lot_nb" => $lot_nb,
                "serial_nb" => $serial_nb,
                "main_id" => $return_id,
                "is_service" => $is_service,
                "main_nb" => $prefix . $ret_num,
                "customer_id" => $this->info['Customer_ID']
            ];
            //            $cost = CommonBusiness::addCostByType($costdata, "add_return_invoice");
            $unit_cost = 0;
            //CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
            //            $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $items['Product_ID'] . '"');
            //            $count_row = $this->db->rowsno($link_query);
            //            if ($count_row == 0) {
            //                $cost = self::updateReturnLinkQuantities($costdata, "add_return_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'] * $quantity;
            //                    $costdata["Quantity"] = $link_qty;
            //                    $costdata["current_quantity"] = $link['current_quantity'] * $quantity;
            //                    $costdata["Product_ID"] = $link['sub_product_id'];
            //                    $costdata["uom_id"] = $link['UOM_ID'];
            //                    $cost = self::updateReturnLinkQuantities($costdata, "add_return_invoice", ($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($items['Product_ID'], $items['UOM_ID'], $quantity, $items['Product_Quantity'], '+', 0, $option_arr);
            //               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'];
                $tmp_cst_qty = 0;
                if ($ProductQuantityRate != 0 && $items["Product_Quantity"] != 0)
                    $tmp_cst_qty = ($link['Quantity'] / ($ProductQuantityRate * $items["Product_Quantity"]));
                $cost = self::updateLinkQuantities($costdata, "add_return_invoice", $link['operation']) * $tmp_cst_qty;
                //                    echo $cost.='==';
                $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
            }
            $details = [
                &$return_id,
                &$items['Product_ID'],
                &$quantity,
                &$Product_Total_Price,
                &$items['Product_Quantity'],
                &$items['Net_Price'],
                &$unit_cost,
                &$items['vat_percent'],
                &$items['vat_amount'],
                &$items['vat2_percent'],
                &$items['vat2_amount'],
                &$items['UOM_ID'],
                &$items['expiry_date'], &$lot_nb, &$serial_nb, &$items['Item_Discount'], &$is_damaged
            ];

            $this->db->prepare_Stmt("
                                        INSERT
                                        INTO
                                            tbl_accounting_return_items
                                        (
                                            Return_Invoice_ID,
                                            Product_ID,
                                            Return_Product_Quantity,
                                            Return_Product_Total,
                                            Item_Quantity_Current,
                                            unit_price,
                                            unit_cost,
                                            vat_percent,
                                            vat_amount,vat2_percent,vat2_amount,
                                            UOM_ID,
                                            expiry_date,lot_nb,serial_nb,Product_Discount,is_damaged
                                        )
                                            VALUES
                                        (
                                            ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
                                        )
                                    ", $details);
            $detail_id = $this->db->id();
            if ($is_damaged == 1) {
                $damaged_array[] = [
                    'UOM_ID' => $items['UOM_ID'],
                    'quantity' => $items["Product_Quantity"],
                    'Product_ID' => $items['Product_ID'],
                    'expiry_date' => $items['expiry_date'],
                    'lot_nb' => $lot_nb,
                    'serial_nb' => $serial_nb,
                    'return_detail_id' => $detail_id,
                    'is_service' => $is_service];
//                $damaged_array = ['damaged_date' => $today,
//                    'UOM_ID' => $items['UOM_ID'],
//                    'Damaged_Quantity' => $items["Product_Quantity"],
//                    'Product_ID' => $items['Product_ID'],
//                    'expiry_date' => $items['expiry_date'],
//                    'lot_nb' => $lot_nb,
//                    'serial_nb' => $serial_nb,
//                    'return_detail_id' => $detail_id,
//                    'Depot_ID' => $depot_id,
//                    'customer_id' => $this->info['Customer_ID'],
//                    'logged_id' => $this->info['Logged_ID'],
//                    'Damaged_Reason' => 'Automatic damage from return'];
//                $this->ware_house_depot->setData($damaged_array)->addDamagedQuantities();
            }
        }
        if (!empty($damaged_array)) {
            $damaged_data = [
                'damaged_date' => $today,
                'return_id' => $return_id,
                'Depot_ID' => $depot_id,
                'is_actual' => $is_actual,
                'customer_id' => $this->info['Customer_ID'],
                'logged_id' => $this->info['Logged_ID'],
                'created_logged_id' => $this->info['Logged_ID'],
                'note' => 'Automatic damage from return',
                'Products' => $damaged_array];
            $this->depot->setData($damaged_data)->add_damage();
        }
        //        echo"<pre>";die(print_r($prod_arr));
        $prod_str = implode( ',',$prod_ids_arr);
        $prod_trans_arr = CommonBusiness::get_item_acc_transactions($prod_arr, $prod_str, 'rin', $account_debit, $this->info['Invoice_Discount'], null, 0, $this->info['tax_amount']);


        $jv = JV::returnJV($is_actual);
        $type_2 = "Credit";
        $type_1 = "Debit";
        $ref = "Ret." . $prefix . $ret_num;
        $ret_desc = 'Return items';
        foreach ($prod_trans_arr as $trans) {
            //            $trans_desc = $trans[]
            if (isset($trans['main'])) {
                $trans_main = $trans['main'];
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => 'ret',
                    "Transaction_Account" => $trans_main['trans_account'],
                    "Transaction_Type" => 'Debit',
                    "Transaction_Amount" => $trans_main['trans_amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "Transaction_Description" => (empty($trans_main['trans_desc']) ? $ret_desc : $trans_main['trans_desc']),
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $this->info['second_rate'],
                    "main_id" => $return_id,
                    "main_type" => $main_type,
                    "main_nb" => $ret_num,
                    "prefix" => $prefix,
                    "subtype" => 'ret',
                    "due_date" => $today,
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($data_trans, $is_actual);
            }


            if (isset($trans['person'])) {
                $trans_person = $trans['person'];
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref,
                    "Transaction_Account" => $account_credit,
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $trans_person['trans_amount'],
                    "Transaction_Date" => $today,
                    "Currency_ID" => $this->info['Invoice_Currency'],
                    "Logged_ID" => $this->info['Logged_ID'],
                    "Transaction_Description" => (empty($trans_person['trans_desc']) ? $ret_desc : $trans_person['trans_desc']),
                    "Current_Ex_Rate" => $rate,
                    "second_currency_rate" => $this->info['second_rate'],
                    "main_id" => $return_id,
                    "main_type" => $main_type,
                    "main_nb" => $ret_num,
                    "prefix" => $prefix,
                    "due_date" => $today,
                    "salesman_id" => $sales_id
                ];
                JV::addTransaction($data_trans, $is_actual);
                //                 $error = $this->db->error();
                //            die(print_r($error));
            }
        }
        //        $dat_1 = [
        //            "JV_ID" => $jv,
        //            "Transaction_Reference" => 'ret',
        //            "Transaction_Account" => $account_debit,
        //            "Transaction_Type" => $type_1,
        //            "Transaction_Amount" => $debit_amount,
        //            "Transaction_Date" => $today,
        //            "Currency_ID" => $this->info['Invoice_Currency'],
        //            "Logged_ID" => $this->info["Logged_ID"],
        //            "Transaction_Description" => $ret_desc,
        //            "Current_Ex_Rate" => "0",
        //            "main_id" => $return_id,
        //            "main_type" => $main_type
        //        ];
        //        JV::addTransaction($dat_1);
        //        $dat_2 = [
        //            "JV_ID" => $jv,
        //            "Transaction_Reference" => 'ret',
        //            "Transaction_Account" => $account_credit,
        //            "Transaction_Type" => $type_2,
        //            "Transaction_Amount" => $credit_amount,
        //            "Transaction_Date" => $today,
        //            "Currency_ID" => $this->info['Invoice_Currency'],
        //            "Logged_ID" => $this->info["Logged_ID"],
        //            "Transaction_Description" => $ret_desc,
        //            "Current_Ex_Rate" => "0",
        //            "main_id" => $return_id,
        //            "main_type" => $main_type
        //        ];
        //        JV::addTransaction($dat_2);
        //die(print_r($dat_2));
          
        $dat_6 = array(
            "JV_ID" => $jv,
            "Transaction_Reference" => $ref,
            "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" => $tax_type,
            "Transaction_Amount" => $this->info['vat1_total'],
            "Transaction_Date" => $today,
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info["Logged_ID"],
            "Transaction_Description" => $ret_desc,
            "Current_Ex_Rate" => $rate,
            "second_currency_rate" =>  $this->info['second_rate'],
            "main_id" => $return_id,
            "main_type" => $main_type,
            "main_nb" => $ret_num,
            "prefix" => $prefix,
            "due_date" => $today,
            "salesman_id" => $sales_id,
            "subtype" => "vat1"
        );
        JV::addTransaction($dat_6, $is_actual);
        $dat_6 = array(
            "JV_ID" => $jv,
            "Transaction_Reference" => $ref,
            "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" => $tax_type,
            "Transaction_Amount" => $this->info['vat2_total'],
            "Transaction_Date" => $today,
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info["Logged_ID"],
            "Transaction_Description" => $ret_desc,
            "Current_Ex_Rate" => $rate,
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $return_id,
            "main_type" => $main_type,
            "main_nb" => $ret_num,
            "prefix" => $prefix,
            "due_date" => $today,
            "salesman_id" => $sales_id,
            "subtype" => "vat2"
        );
        JV::addTransaction($dat_6, $is_actual);
        $cash_account = smc_session()['user_accounts']['cash_account_id'];
        $other_account = smc_session()['user_accounts']['other_account_id'];
        //        $error = $this->db->error();
        //        die(print_r($dat_6));

        $dat_4 = [
            "JV_ID" => $jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $cash_account,
            "Transaction_Type" => $payment_type,
            "Transaction_Amount" => $this->info['cash_amount'],
            "Transaction_Date" => $today,
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info["Logged_ID"],
            "Transaction_Description" => $ret_desc,
            "Current_Ex_Rate" => $rate,
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $return_id,
            "main_type" => $main_type,
            "main_nb" => $ret_num,
            "prefix" => $prefix,
            "subtype" => 'cash',
            "due_date" => $today,
            "salesman_id" => $sales_id
        ];
        JV::addTransaction($dat_4, $is_actual);
        $dat_41 = [
            "JV_ID" => $jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $account_credit,
            "Transaction_Type" => 'Debit',
            "Transaction_Amount" => ($this->info['cash_amount'] + $this->info['other_amount']),
            "Transaction_Date" => $today,
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info["Logged_ID"],
            "Transaction_Description" => $ret_desc,
            "Current_Ex_Rate" => $rate,
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $return_id,
            "main_type" => $main_type,
            "main_nb" => $ret_num,
            "prefix" => $prefix,
            "due_date" => $today,
            "salesman_id" => $sales_id
        ];
        JV::addTransaction($dat_41, $is_actual);
        //        $dat_42 = [
        //            "JV_ID" => $jv,
        //            "Transaction_Reference" => $ref,
        //            "Transaction_Account" => $account_credit,
        //            "Transaction_Type" => 'Credit',
        //            "Transaction_Amount" => $this->info['Invoice_Net_Total'],
        //            "Transaction_Date" => $today,
        //            "Currency_ID" => $this->info['Invoice_Currency'],
        //            "Logged_ID" => $this->info["Logged_ID"],
        //            "Transaction_Description" => $ret_desc,
        //            "Current_Ex_Rate" => "0",
        //            "main_id" => $return_id,
        //            "main_type" => $main_type
        //        ];
        //        JV::addTransaction($dat_42);
        //$error = $this->db->error();
        //        die(print_r($error));
        $dat_5 = ["JV_ID" => $jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $other_account,
            "Transaction_Type" => $payment_type,
            "Transaction_Amount" => $this->info['other_amount'],
            "Transaction_Date" => $today,
            "Currency_ID" => $this->info['Invoice_Currency'],
            "Logged_ID" => $this->info["Logged_ID"],
            "Transaction_Description" => $ret_desc,
            "Current_Ex_Rate" => $rate,
            "second_currency_rate" => $this->info['second_rate'],
            "main_id" => $return_id,
            "main_type" => $main_type,
            "main_nb" => $ret_num,
            "prefix" => $prefix,
            "subtype" => $this->info['check_credit'] == 2 ? 'credit' : 'check',
            "due_date" => $today,
            "salesman_id" => $sales_id
        ];
        JV::addTransaction($dat_5, $is_actual);
        //        $error = $this->db->error();
        //                echo"here";die(print_r($error));

        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query("COMMIT");
            return $return_id;
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query("ROLLBACK");
            return array_unique($error);
        }
    }

    public function getTotalDelivery() {
        $query = $this->db->query('SELECT count(*) as total_delivery FROM `tbl_invoices` WHERE `Invoice_Status` = 3  and Is_Closed <> 1 and table_id = 0 and is_actual = "' . $this->info['is_actual'] . '"');
        $row = $this->db->assoc($query);
        return $row['total_delivery'];
    }

    public function getReturnById($id) {
        $data = array();
        //        $printers = array();
        //        $printers_id = array();
        $main_query = $this->db->query('SELECT * FROM customer_return_list WHERE Return_Invoice_ID = "' . $id . '"');
        $main_arr = $this->db->assoc($main_query);
        $data['main_invoice'] = $main_arr;
        $query = $this->db->query('SELECT * FROM returned_main_detailed where `Return_Invoice_ID` = "' . $id . '" ');
        while ($row = $this->db->assoc($query)) {
            $row['unit_price'] = CommonFunctions::formatNumber($row['unit_price']);
            $row['Return_Product_Total'] = CommonFunctions::formatNumber($row['Return_Product_Total']);
            $data['return_details'][] = $row;
        }
        //        $data['Org'] = self::getOrganizationAddress();
        return $data;
    }

    //    public function deleteParkedInvoice($id_arr) {
    //        $this->db->query('START TRANSACTION');
    //        foreach ($id_arr as $id) {
    //            //            $depot_query = $this->db->query('select Depot_ID from tbl_invoices where Invoice_ID_Auto = "' . $id . '"');
    //            //            $depot_id = $this->db->assoc($depot_query)['Depot_ID'];
    //            $this->db->prepare_Stmt('delete from tbl_accounting_transactions where main_id= ? and main_type="inv"', [&$id]);
    //            //        self::editInvoiceQuantities($id, $depot_id);
    //
    //            $this->edit_old_details_qty_cost($id);
    //            $this->db->prepare_Stmt('delete from tbl_invoice_products_details where Invoice_ID_Auto= ? ', [&$id]);
    //            $this->db->prepare_Stmt('update tbl_invoices set Invoice_Sub_Total = 0,Invoice_Net_Total =0, Invoice_Paid_Amount=0,Invoice_Shipping=0,Invoice_Status = 2 where Invoice_ID_Auto= ? ', [&$id]);
    //        }
    //        $error = $this->db->error();
    //        if (empty($error)) {
    //            $this->db->query('COMMIT');
    //        } else {
    //            $this->db->query('ROLLBACK');
    //        }
    //        return array_unique($error);
    //    }
    //    public function editInvoiceQuantities($id, $depot_id) {
    //        $query = $this->db->query("SELECT 
    //                                        if(isNull(l.link_id), p.Product_ID, l.sub_product_id) as sub_product_id,
    //                                        if(isNull(l.link_id), p.Item_Quantity_Current, (p.Item_Quantity_Current * l.quantity)) as Quantity,
    //                                        if(isNull(l.link_id), '-', l.operation) as operation
    //                                    FROM 
    //                                        tbl_invoice_products_details p
    //                                    left JOIN
    //                                        tbl_products_link l
    //                                    on p.Product_ID = l.main_product_id
    //                                    WHERE 
    //                                        p.Invoice_ID_Auto = '" . $id . "'
    //                ");
    //        while ($row = $this->db->assoc($query)) {
    //
    //            $up_quan = [&$row['Quantity'], &$row['sub_product_id']];
    //            $this->db->prepare_Stmt("UPDATE 
    //                                                tbl_stock_products 
    //                                        SET 
    //                                                Product_Quantity = Product_Quantity " . ($row['operation'] == '+' ? '-' : '+' ) . " ?
    //                                        WHERE 
    //                                                Product_ID = ? 
    //                                    ", $up_quan);
    //
    //            $dep_dat = [&$row['Quantity'], &$row['sub_product_id'], &$depot_id];
    //            $this->db->prepare_Stmt("UPDATE 
    //                                            tbl_stock_product_location 
    //                                    SET 
    //                                            Product_Depot_Quantity = Product_Depot_Quantity " . ($row['operation'] == '+' ? '-' : '+' ) . " ?
    //                                    WHERE 
    //                                            Location_Product_ID = ? 
    //                                    AND 
    //                                            Product_Depot_ID = ?
    //                                    ", $dep_dat);
    //        }
    //    }



    public function getCustomerAccount($customer_id) {

        $query = $this->db->query('SELECT Account_ID,Account_Code
                                FROM tbl_chart_of_accounts 
                                WHERE main_id = "' . $customer_id . '"
                                AND main_type = "cust" and sub_type = "main"	');


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

    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);
            $dep_dat = [&$data['depot_id'], &$data['Product_ID'], &$sub_qty, &$data['Quantity']];
            $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 updateReturnLinkQuantities($data, $method, $operation) {
        $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 = &$data['Quantity'] * (-1);
            $dep_dat = [&$data['depot_id'], &$data['Product_ID'], &$sub_qty, &$data['Quantity']];
            $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 getMaxReturn($branch_id) {
        $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'];
        $prefix = smc_session()['user_accounts']['serial_prefix'] ? smc_session()['user_accounts']['serial_prefix'] : $branch_prefix;

        $yearid = $this->year_id;

        $query = $this->db->query('SELECT MAX(Return_ID) AS Entry_ID FROM tbl_accounting_return_invoices 
            where current_year_id = "' . $yearid . '" 
                and invoice_prefix = "' . $prefix . '"
                    and Is_Actual = 0
                        AND Is_Customer_Invoice = 1

                    ');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $Invoice = $row['Entry_ID'] + 1;
        else
            $Invoice = 1;

        return ['prefix' => $prefix, 'inv_nb' => $Invoice];
    }

    public function edit_old_details_qty_cost($inv_auto_id, $is_delete = 0) {
        $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;
        }

        $trans_type = $is_delete == 1 ? 'delete_invoice' : 'edit_invoice_old';
        $query = $this->db->query("SELECT 
                                        p.Product_ID,
                                        p.Item_Quantity_Current as Current_Quantity,
                                        p.Product_Quantity as Quantity,
                                        p.UOM_ID,
                                        p.unit_cost,p.Product_Net_Price,
                                        i.Invoice_Currency AS Currency_ID,
                                        i.Depot_ID,
                                        i.current_rate,
                                        i.date_time,
                                        p.expiry_date,p.lot_nb,p.serial_nb,pr.is_service,
                                        i.Customer_ID,i.invoice_prefix,i.Invoice_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 = '" . $inv_auto_id . "'
                ");

        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['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("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,
                "main_id" => $inv_auto_id,
                "expiry_date" => $expiry_date,
                "lot_nb" => $lot_nb,
                "serial_nb" => $serial_nb,
                "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);
            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'];
                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, $trans_type, ($link['operation'] == '+' ? '-' : '+'));
            }
            //            $cost = self::updateLinkQuantities($costdata, "edit_invoice_old", ($row['operation'] == '+' ? '-' : '+'));
        }
        return array("Depot_ID" => $depot_id);
    }

    public static function get_open_shift_time($user_id = null, $type = null) {
        $db = DBConnectorFactory::loadDriver();
        $open_time = date('Y-m-d ' . smc_session()['default_setting']['default_start_time']);   //needed if first time use of end shift
        //$user_id = smc_session()['user_logged_id'];
        $cond = ' ';
        if (is_null($type)) {
            if (!empty($user_id))
                $cond .= ' and ((type = 0 && user_id = "' . $user_id . '") || type = 1) ';
        }
        else {
            $cond .= ' and type="' . $type . '" ';
            if (!empty($user_id))
                $cond .= ' and user_id = "' . $user_id . '" ';
        }
        $query_last_close = $db->query('select * from tbl_end_of_shift 
            where true ' . $cond . ' order by close_time desc limit 1');
        $row = $db->assoc($query_last_close);
        if (!empty($row)) {
            $open_time = date('Y-m-d H:i:s', strtotime($row['close_time'] . ' +1 second'));
        }
        return $open_time;
    }

    public function updateDeliveryStatus() {
        $this->db->prepare_Stmt('update tbl_invoices set is_delivery_notified = 1 where Invoice_ID_Auto = ?', [&$this->info['Invoice_ID']]);
        $error = $this->db->error();
        return $error;
    }

    public function submitEndOfShift() {
        $this->db->query('START TRANSACTION');
        $data = array();
        $user_ids = explode(",", $this->info['user_id']);
        $query_user_accounts = $this->db->query("select cash_account_id,User_ID from tbl_users_accounting_accounts where  User_ID IN ({$this->info['user_id']})");
        while ($row = $this->db->assoc($query_user_accounts)) {
            $data[$row['User_ID']] = ['User_ID' => $row['User_ID'], 'cash_account_id' => $row['cash_account_id']];
        }
        foreach ($data as $user) {
            self::end_of_shift($user['User_ID'], $user['cash_account_id'], true);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function end_of_shift($user_id = null, $cash_acc_id = null, $other = false, $is_actual = 0) {
        $close_time = date('Y-m-d H:i:s');
        $logged_id = smc_session()['user_logged_id'];
        $user_id = empty($user_id) ? smc_session()['user_logged_id'] : $user_id;
        $cash_acc_id = empty($cash_acc_id) ? smc_session()['user_accounts']['cash_account_id'] : $cash_acc_id;
        $currency_id = smc_session()['pricing_class_currency'];
        $cur_rate = CurrencyFactory::getLastExRate($currency_id);
        $open_time = Invoicepos::get_open_shift_time($user_id, 0);
        //
        $data = $this->get_end_of_shift_balances($open_time, $close_time, $currency_id, $user_id, $cash_acc_id, $is_actual);
        //                echo"<pre>";die(print_r($data));
        $shift_data = [&$user_id, &$open_time, &$close_time, &$cash_acc_id, &$data['totals']['net_invoices']['amount'],
            &$data['totals']['net_returns']['amount'], &$data['totals']['total_cash']['amount'], &$currency_id, &$cur_rate,
            &$is_actual, &$logged_id, &$close_time];
        $this->db->prepare_Stmt('insert into tbl_end_of_shift (`user_id`, `open_time`, `close_time`, `account_id`,
            `total_net_invoices`, `total_net_returns`, `total_balance`, `Currency_ID`, `current_rate`,is_actual,
            logged_id,date_time)
            values(?,?,?,?,?,?,?,?,?,?,?,?)
            ', $shift_data);
        if (!$other) {
            $shift_id = $this->db->id();
            $error = $this->db->error();
            return [$shift_id, $error];
        }
    }

    public function end_of_day($is_actual = 0) {
        if (smc_session()['default_setting']['disable_end_of_day_table_opened'] == 1) {
            $query_tables = $this->db->query('select * from  tbl_table where status_id = 2 limit 1');
            $tables_count = $this->db->rowsno($query_tables);
            if ($tables_count > 0)
                return ['error', [CommonLanguage::getMessage('opened_table')]];
        }
        if (smc_session()['default_setting']['disable_end_of_day_delivery_opened'] == 1) {
            $query_tables = $this->db->query('select * from  tbl_invoices 
                where invoice_type = 2 and is_committed=0 limit 1');
            $tables_count = $this->db->rowsno($query_tables);
            if ($tables_count > 0)
                return ['error', [CommonLanguage::getMessage('opened_delivery')]];
        }
        if (smc_session()['default_setting']['disable_end_of_day_park_opened'] == 1) {
            $query_tables = $this->db->query('select * from  tbl_invoices 
                where invoice_type = 3 and is_committed=0 limit 1');
            $tables_count = $this->db->rowsno($query_tables);
            if ($tables_count > 0)
                return ['error', [CommonLanguage::getMessage('opened_park')]];
        }

        $close_time = date('Y-m-d H:i:s');
        $user_id = null;
        $cash_acc_id = null;
        $currency_id = smc_session()['pricing_class_currency'];
        $cur_rate = CurrencyFactory::getLastExRate($currency_id);
        $open_time = Invoicepos::get_open_shift_time($user_id, 1);
        $this->info['branch_id'] = empty($this->info['branch_id']) ? NULL : $this->info['branch_id'];
        $logged_id = smc_session()['user_logged_id'];

        //
        $data = $this->get_end_of_shift_balances($open_time, $close_time, null, null, null, $is_actual);
        $shift_data = [&$user_id, &$open_time, &$close_time, &$cash_acc_id, &$data['totals']['net_invoices']['amount'],
            &$data['totals']['net_returns']['amount'], &$data['totals']['total_cash']['amount'], &$currency_id,
            &$cur_rate, &$is_actual, &$this->info['branch_id'], &$logged_id, &$close_time];
        $this->db->prepare_Stmt('insert into tbl_end_of_shift (`user_id`, `open_time`, `close_time`, `account_id`,
            `total_net_invoices`, `total_net_returns`, `total_balance`, `Currency_ID`, `current_rate`,type,
            is_actual,branch_id,logged_id,date_time)
            values(?,?,?,?,?,?,?,?,?,1,?,?,?,?)
            ', $shift_data);
        $shift_id = $this->db->id();
        $error = $this->db->error();
        return [$shift_id, $error];
    }

    public function get_end_of_shift_balances($open_time, $close_time, $currency_id = null, $user_id = null, $account_id = null, $is_actual = 0) {
        $common_cond = '';
        $data = array();
        //if it is date not time
        if (!empty($open_time) && strlen($open_time) <= '10')
            $open_time .= ' 00:00:00';
        if (!empty($close_time) && strlen($close_time) <= '10')
            $close_time .= ' 23:59:59';
        if (!empty($this->info['branch_id']))
            $common_cond .= ' and branch_id = "' . $this->info['branch_id'] . '"';
        //
        $total_cash = 0.0;
        $total_local_cash = 0.0;
        $local_currency = smc_session()['local_currency'];
        $currency_id = empty($currency_id) ? smc_session()['pricing_class_currency'] : $currency_id;
        $cur_rate = CurrencyFactory::getLastExRate($currency_id);
        $sum_net_price = 0;
        $sum_persons = 0;
        $data['total_count'] = ['total_nb_persons' => 0, 'total_tables' => 0, 'total_void_invoices' => 0, 'total_void_items' => 0];
        $data['total_amounts'] = ['total_amount_tables' => 0, 'total_amount_delivery' => 0,
            'total_amount_takeaway' => 0, 'total_amount_void_invoices' => 0, 'total_amount_void_items' => 0, 'average_amount_on_person' => 0];
        $data['totals']['net_invoices'] = ['amount' => 0, 'local_amount' => 0, 'from_invoice' => 0, 'to_invoice' => 0];
        $data['totals']['vat_invoices'] = ['amount' => 0, 'local_amount' => 0];
        $data['totals']['vat1_invoices'] = ['amount' => 0, 'local_amount' => 0];
        $data['totals']['vat2_invoices'] = ['amount' => 0, 'local_amount' => 0];
        $data['totals']['shipping'] = ['amount' => 0, 'local_amount' => 0];
        $invoice_query = $this->db->query('select * from tbl_invoices 
                where date_created between "' . $open_time . '"  and "' . $close_time . '" ' . (empty($user_id) ? '' : ' 
                    and created_logged_id = "' . $user_id . '" ' ) . ' and is_actual="' . $is_actual . '" ' . $common_cond);
                     
        while ($row = $this->db->assoc($invoice_query)) {
            $total_invoice_with_rate = ($row['Invoice_Shipping'] + $row['Invoice_Net_Total']) * $row['current_rate'];
            $data['total_count']['total_nb_persons'] += $row['Persons_Count'];
            if ($row['table_id'] != 0) {
                $data['total_count']['total_tables'] ++;
                $data['total_amounts']['total_amount_tables'] += $total_invoice_with_rate;
                if ($row['Persons_Count'] != 0 && $total_invoice_with_rate != 0) {
                    $sum_net_price += $total_invoice_with_rate;
                    $sum_persons += $row['Persons_Count'];
                }
            }
            $data['totals']['net_invoices']['local_amount'] += $total_invoice_with_rate;
            $data['totals']['vat_invoices']['local_amount'] += ($row['Invoice_VAT'] * $row['current_rate']);
            $data['totals']['vat1_invoices']['local_amount'] += ($row['vat1_total'] * $row['current_rate']);
            $data['totals']['vat2_invoices']['local_amount'] += ($row['vat2_total'] * $row['current_rate']);
            $data['totals']['shipping']['local_amount'] += ($row['Invoice_Shipping'] * $row['current_rate']);
            if ($currency_id == $row['Invoice_Currency']) {
                $data['totals']['net_invoices']['amount'] += ($row['Invoice_Shipping'] + $row['Invoice_Net_Total']);
                $data['totals']['vat_invoices']['amount'] += $row['Invoice_VAT'];
                $data['totals']['vat1_invoices']['amount'] += $row['vat1_total'];
                $data['totals']['vat2_invoices']['amount'] += $row['vat2_total'];
                $data['totals']['shipping']['amount'] += $row['Invoice_Shipping'];
            } else {
                $data['totals']['net_invoices']['amount'] += ($total_invoice_with_rate) / $cur_rate;
                $data['totals']['vat_invoices']['amount'] += (($row['Invoice_VAT'] * $row['current_rate']) / $cur_rate);
                $data['totals']['vat2_invoices']['amount'] += (($row['vat1_total'] * $row['current_rate']) / $cur_rate);
                $data['totals']['vat2_invoices']['amount'] += (($row['vat2_total'] * $row['current_rate']) / $cur_rate);
                $data['totals']['shipping']['amount'] += (($row['Invoice_Shipping'] * $row['current_rate']) / $cur_rate);
            }

             if (smc_session()['local_currency'] == $row['Invoice_Currency']){
                $data['totals']['net_invoices']['local_currency_amount']  += ($row['Invoice_Shipping'] + $row['Invoice_Net_Total']);

            }else if(smc_session()['second_currency']['id'] == $row['Invoice_Currency']){
                $data['totals']['net_invoices']['second_currency_amount']  += ($row['Invoice_Shipping'] + $row['Invoice_Net_Total']);

            }
            // if (smc_session()['local_currency'] == $row['Invoice_Currency']){
            //     $data['totals']['net_invoices']['cash_local_currency_amount']  +=  $row['first_cash_Invoice_Paid_Amount'];
            //     $data['totals']['net_invoices']['cash_second_currency_amount']  +=  $row['second_cash_Invoice_Paid_Amount'];
            // }else if(smc_session()['second_currency']['id'] == $row['Invoice_Currency']){
            //     $data['totals']['net_invoices']['cash_local_currency_amount']  +=  $row['second_cash_Invoice_Paid_Amount'];
            //     $data['totals']['net_invoices']['cash_second_currency_amount']  +=  $row['first_cash_Invoice_Paid_Amount'];

            // }



            if(!empty($row['first_cash_Invoice_Paid_Amount']) || !empty($row['second_cash_Invoice_Paid_Amount'])){
                if (smc_session()['local_currency'] == $row['Invoice_Currency']){
                    $data['totals']['net_invoices']['cash_local_currency_amount']  +=  $row['first_cash_Invoice_Paid_Amount']  ;
                    $data['totals']['net_invoices']['cash_second_currency_amount']  +=  $row['second_cash_Invoice_Paid_Amount']  ;

                }  if(smc_session()['second_currency']['id'] == $row['Invoice_Currency']){
                    $data['totals']['net_invoices']['cash_second_currency_amount']  += ($row['first_cash_Invoice_Paid_Amount']);
                    $data['totals']['net_invoices']['cash_local_currency_amount']  += ($row['second_cash_Invoice_Paid_Amount']);

                }
            }else if(!empty($row['Invoice_Paid_Amount'])){
                if (smc_session()['local_currency'] == $row['Invoice_Currency']){
                    $data['totals']['net_invoices']['cash_local_currency_amount']  += ($row['Invoice_Paid_Amount'] );

                }else if(smc_session()['second_currency']['id'] == $row['Invoice_Currency']){
                    $data['totals']['net_invoices']['cash_second_currency_amount']  += ($row['Invoice_Paid_Amount']);

                }

            }




            if ($row['Is_Delivery'] == 1)
                $data['total_amounts']['total_amount_delivery'] += $total_invoice_with_rate;
            if ($row['Inv_Type'] == 2 && $row['table_id'] == 0)
                $data['total_amounts']['total_amount_takeaway'] += $total_invoice_with_rate;
            if (!is_null($row['reason_id'])) {
                $data['total_count']['total_void_invoices'] ++;
                $data['total_amounts']['total_amount_void_invoices'] += ($row['invoice_void_total'] * $row['current_rate']);
            }
        }
        if ($sum_net_price != 0 && $sum_persons != 0)
            $data['total_amounts']['average_amount_on_person'] = $sum_net_price / $sum_persons;
        $void_items_query = $this->db->query('select void.*, inv.current_rate
                                              from tbl_invoice_products_void void 
                                              inner join tbl_invoices inv using(Invoice_ID_Auto)
                                              where inv.date_created between "' . $open_time . '" 
                                            and "' . $close_time . '" ' . (empty($user_id) ? '' : ' 
                                            and inv.created_logged_id = "' . $user_id . '" ' ) . ' and inv.is_actual="' . $is_actual . '" ' . $common_cond);
        while ($row = $this->db->assoc($void_items_query)) {
            $data['total_count']['total_void_items'] += $row['Item_Quantity_Current'];
            $data['total_amounts']['total_amount_void_items'] += ($row['Product_Total_Price'] * $row['current_rate']);
        }
        //
        $net_inv_query = $this->db->query('select sum(if(' . $currency_id . '= Currency_ID,Return_Net_Total,Return_Net_Total*current_rate/' . $cur_rate . ')) as amount
				, sum(if(' . $currency_id . '= Currency_ID,Invoice_VAT,Invoice_VAT*current_rate/' . $cur_rate . ')) as vat_amount
				, sum(if(' . $currency_id . '= Currency_ID,vat1_total,vat1_total*current_rate/' . $cur_rate . ')) as vat1_amount
				, sum(if(' . $currency_id . '= Currency_ID,vat2_total,vat2_total*current_rate/' . $cur_rate . ')) as vat2_amount
				, sum(Return_Net_Total*current_rate) as local_amount, sum(Invoice_VAT*current_rate) as local_vat_amount,
                                sum(vat1_total*current_rate) as local_vat1_amount, 
                                sum(vat2_total*current_rate) as local_vat2_amount
			from tbl_accounting_return_invoices where date_created between "' . $open_time . '" and "' . $close_time . '"
				' . (empty($user_id) ? '' : ' and created_logged_id = "' . $user_id . '" ' ) . '  and Is_Actual="' . $is_actual . '" ' . $common_cond);
        $return_assoc = $this->db->assoc($net_inv_query);
        //        if (!empty($return_assoc['amount'])) {
        $data['totals']['net_returns']['amount'] = !empty($return_assoc['amount']) ? $return_assoc['amount'] : 0;
        $data['totals']['net_returns']['local_amount'] = !empty($return_assoc['local_amount']) ? $return_assoc['local_amount'] : 0;
        $data['totals']['vat_returns']['amount'] = !empty($return_assoc['vat_amount']) ? $return_assoc['vat_amount'] : 0;
        $data['totals']['vat_returns']['local_amount'] = !empty($return_assoc['local_vat_amount']) ? $return_assoc['local_vat_amount'] : 0;
        $data['totals']['vat1_returns']['amount'] = !empty($return_assoc['vat1_amount']) ? $return_assoc['vat1_amount'] : 0;
        $data['totals']['vat1_returns']['local_amount'] = !empty($return_assoc['local_vat1_amount']) ? $return_assoc['local_vat1_amount'] : 0;
        $data['totals']['vat2_returns']['amount'] = !empty($return_assoc['vat2_amount']) ? $return_assoc['vat2_amount'] : 0;
        $data['totals']['vat2_returns']['local_amount'] = !empty($return_assoc['local_vat2_amount']) ? $return_assoc['local_vat2_amount'] : 0;
        //
        $data['totals']['vat_inv_ret'] = array();
        $data['totals']['vat_inv_ret']['amount'] = ($data['totals']['vat_invoices']['amount'] - $data['totals']['vat_returns']['amount']);
        $data['totals']['vat_inv_ret']['local_amount'] = ($data['totals']['vat_invoices']['local_amount'] - $data['totals']['vat_returns']['local_amount']);
        $data['totals']['vat1_inv_ret'] = array();
        $data['totals']['vat1_inv_ret']['amount'] = ($data['totals']['vat1_invoices']['amount'] - $data['totals']['vat1_returns']['amount']);
        $data['totals']['vat1_inv_ret']['local_amount'] = ($data['totals']['vat1_invoices']['local_amount'] - $data['totals']['vat1_returns']['local_amount']);
        $data['totals']['vat2_inv_ret'] = array();
        $data['totals']['vat2_inv_ret']['amount'] = ($data['totals']['vat2_invoices']['amount'] - $data['totals']['vat2_returns']['amount']);
        $data['totals']['vat2_inv_ret']['local_amount'] = ($data['totals']['vat2_invoices']['local_amount'] - $data['totals']['vat2_returns']['local_amount']);
        //
        $data['totals']['deposit'] = $data['totals']['withdrawal'] = $data['totals']['payments'] = $data['totals']['receipts'] = $data['totals']['invoices'] = $data['totals']['returns'] = $data['totals']['expenses'] = ['amount' => 0, 'local_amount' => 0];
        $cash_accs = CommonACC::get_pay_acc_by_type('cash');
        $types = array("deposit" => ["type" => "dwt", "op" => "+"],
            "withdrawal" => ["type" => "dwt", "op" => "-"],
            "payments" => ["type" => "pay", "op" => "-"],
            "receipts" => ["type" => "rec", "op" => "+"],
            "invoices" => ["type" => "inv", "op" => "+"],
            "returns" => ["type" => "rin", "op" => "-"],
            "expenses" => ["type" => "exp", "op" => "-"]);
        foreach ($types as $key => $type) {
            if (empty($account_id)) {
                if (!empty($cash_accs)) {
                    $query = $this->db->query('select sum(if(' . $currency_id . '=Currency_ID,Transaction_Amount,((local_amount)/' . $cur_rate . '))) as amount,
				sum(local_amount) as local_amount
                                from tbl_accounting_transactions where date_time between "' . $open_time . '" and "' . $close_time . '" and main_type ="' . $type['type'] . '"
 and if("' . $type['type'] . '"="dwt",(if("' . $type['op'] . '"="+",  Transaction_Type="Debit",  Transaction_Type="Credit"  )),"1=1")
				 and Account_ID in (' . implode(',', $cash_accs) . ')  and is_actual="' . $is_actual . '" ' . $common_cond);
                    $type_row = $this->db->assoc($query);
                    if (!empty($type_row['amount'])) {
                        $data['totals'][$key] = $type_row;
                        $total_cash += $data['totals'][$key]['amount'] * ($type['op'] == '+' ? 1 : -1);
                        $total_local_cash += $data['totals'][$key]['local_amount'] * ($type['op'] == '+' ? 1 : -1);
                    }
                }
            } else {
                $query = $this->db->query('select sum(if(' . $currency_id . '=Currency_ID,Transaction_Amount,((local_amount)/' . $cur_rate . '))) as amount,
				sum(local_amount) as local_amount
            from tbl_accounting_transactions where date_time between "' . $open_time . '" and "' . $close_time . '" and main_type ="' . $type['type'] . '" 
				' . (empty($account_id) ? '' : ' and Account_ID = "' . $account_id . '" and if("' . $type['type'] . '"="dwt",(if("' . $type['op'] . '"="+",  Transaction_Type="Debit",  Transaction_Type="Credit"  )),"1=1")' ) . ' 
				' . (empty($user_id) ? '' : ' and Logged_ID = "' . $user_id . '" ' ) . '  and is_actual="' . $is_actual . '" ' . $common_cond);
                $type_row = $this->db->assoc($query);
                if (!empty($type_row['amount'])) {
                    $data['totals'][$key] = $type_row;
                    $total_cash += $data['totals'][$key]['amount'] * ($type['op'] == '+' ? 1 : -1);
                    $total_local_cash += $data['totals'][$key]['local_amount'] * ($type['op'] == '+' ? 1 : -1);
                }
            }
        }
        $data['totals']['total_cash']['amount'] = $total_cash;
        $data['totals']['total_cash']['local_amount'] = $total_local_cash;
        $data['open_time'] = $open_time;
        $data['close_time'] = $close_time;
        $data['currency_id'] = $currency_id;
        $data['currency_symbol'] = CurrencyFactory::getCurrencySymbol($currency_id);
        $data['username'] = empty($user_id) ? '' : User::get_username_by_id($user_id);
        $data['is_user_with_data'] = false;
        if ($data['total_count']['total_nb_persons'] || $data['total_count']['total_tables'] || $data['total_count']['total_void_invoices'] ||
                $data['total_count']['total_void_items'] || $data['total_amounts']['total_amount_delivery'] || $data['total_amounts']['total_amount_takeaway'] ||
                $data['totals']['net_invoices']['amount'] || $data['totals']['net_returns']['amount'] || $data['totals']['receipts']['amount'] ||
                $data['totals']['total_cash']['amount'] || $data['totals']['expenses']['amount'] || $data['totals']['returns']['amount'] ||
                $data['totals']['deposit']['amount'] || $data['totals']['withdrawal']['amount'] || $data['totals']['payments']['amount'] ||
                $data['totals']['invoices']['amount'])
            $data['is_user_with_data'] = true;
        //
               // echo"<pre>";die(print_r($data)) ;
        return $data;
    }

    public function getCategoryTotals($open_time, $close_time, $empty_category) {
        $data = array();
        $total = 0;
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and invoices.branch_id = "' . $this->info['branch_id'] . '" ';
        $total_query = $this->db->query('select 
                                        sum((details.Product_Total_Price+vat_amount+vat2_amount)* invoices.current_rate) as  total_category_amount,
                                        sum((details.Product_Total_Price)* invoices.current_rate) as  total_category_amount_without_vat
                                        from tbl_invoice_products_details details
                                        inner join tbl_stock_products products on details.Product_ID = products.Product_ID
                                        inner join tbl_product_cat category on category.Cat_ID = products.Category_ID
                                        inner join tbl_invoices invoices on details.Invoice_ID_Auto = invoices.Invoice_ID_Auto
                                        where invoices.date_created between "' . $open_time . '" 
                                        and "' . $close_time . '"  ' . $condition);
        $total_assoc = $this->db->assoc($total_query);
        if (!empty($total_assoc['total_category_amount'])) {
            $total = $total_assoc['total_category_amount'];
            $total_without_vat = $total_assoc['total_category_amount_without_vat'];
        }
        if (!empty($empty_category)) {
            $category_query = $this->db->query('select Cat_ID,Cat_Name,0 as percentage,0 as current_total_category_amount,
                0 as current_total_category_amount_without_vat
                from tbl_product_cat order by order_id asc');
            while ($row_category = $this->db->assoc($category_query)) {
                $data[$row_category['Cat_ID']] = $row_category;
            }
        }
        $invoice_query = $this->db->query('select sum((details.Product_Total_Price+details.vat_amount+details.vat2_amount)* invoices.current_rate) as  total_category_amount,
            sum((details.Product_Total_Price)* invoices.current_rate) as  total_category_amount_without_vat,
                                                  category.Cat_ID,
                                                  category.Cat_Name
                                        from tbl_invoice_products_details details
                                        inner join tbl_stock_products products on details.Product_ID = products.Product_ID
                                        inner join tbl_product_cat category on category.Cat_ID = products.Category_ID
                                        inner join tbl_invoices invoices on details.Invoice_ID_Auto = invoices.Invoice_ID_Auto
                                        where invoices.date_created between "' . $open_time . '" 
                                        and "' . $close_time . '"  ' . $condition . '
                                        group by category.Cat_ID 
                                        order by category.order_id asc ');
        while ($row = $this->db->assoc($invoice_query)) {
            $row['percentage'] = CommonFunctions::formatNumber(empty($total) ? 0 : (($row['total_category_amount'] * 100) / $total));
            $row['percentage_without_vat'] = CommonFunctions::formatNumber(empty($total_without_vat) ? 0 : (($row['total_category_amount_without_vat'] * 100) / $total_without_vat));
            $row['current_total_category_amount'] = CommonFunctions::formatNumber($row['total_category_amount']);
            $row['current_total_category_amount_without_vat'] = CommonFunctions::formatNumber($row['total_category_amount_without_vat']);
            $data[$row['Cat_ID']] = $row;
        }
        return $data;
    }

    public function getTotalSoldItems($open_time, $close_time, $with_format = false) {
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and u.branch_id = "' . $this->info['branch_id'] . '" ';
        $data = array('items' => array(), 'total_quantity' => 0, 'sub_total' => 0,
            'vat_total' => 0, 'total' => 0, 'vat1_total' => 0, 'vat2_total' => 0);
        $query = $this->db->query('select Date,
                                          SUM(Quantity) as total_qty,
                                          SUM((vat_amount+vat2_amount)*current_rate) as total_vat,
                                          SUM(vat_amount*current_rate) as total_vat1,
                                          SUM(vat2_amount*current_rate) as total_vat2,
                                          SUM(Product_Total_Price*current_rate) as sub_total,
                                          Item_Name,Code,Logged_ID,Currency_Symbol,UOM_Name 
                                    from product_mov_invoice u 
                                    where u.date_created between "' . $open_time . '" AND "' . $close_time . '" 
                                    AND current_year_id="' . $this->year_id . '" ' . $condition . '
                                    GROUP BY u.Product_ID');
        while ($row = $this->db->assoc($query)) {
            //$row['total_price'] = ($row['sub_total'] + $row['total_vat']);
            $row['current_total_price'] = ($row['sub_total'] + $row['total_vat']);
            $data['total_quantity'] += $row['total_qty'];
            $data['sub_total'] += $row['sub_total'];
            $data['vat_total'] += $row['total_vat'];
            $data['vat1_total'] += $row['total_vat1'];
            $data['vat2_total'] += $row['total_vat2'];
            $data['total'] += $row['current_total_price'];
            //
            if ($with_format) {
                $row['total_qty'] = CommonFunctions::formatNumber($row['total_qty']);
                $row['current_total_price'] = CommonFunctions::formatNumber($row['current_total_price']);
            }
            $data['items'][] = $row;
        }
        if ($with_format) {
            $data['total_quantity'] = CommonFunctions::formatNumber($data['total_quantity']);
            $data['sub_total'] = CommonFunctions::formatNumber($data['sub_total']);
            $data['vat_total'] = CommonFunctions::formatNumber($data['vat_total']);
            $data['vat1_total'] = CommonFunctions::formatNumber($data['vat1_total']);
            $data['vat2_total'] = CommonFunctions::formatNumber($data['vat2_total']);
            $data['total'] = CommonFunctions::formatNumber($data['total']);
        }
        //        echo"<pre>";die(print_r($data));
        return $data;
    }

    public function getTotalVoidItems($open_time, $close_time) {
        $data = array();
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and inv.branch_id = "' . $this->info['branch_id'] . '"';
        $query = $this->db->query('select Sum(void.Product_Total_Price *  inv.current_rate) as current_total_price,
                                          Sum(void.Item_Quantity_Current) as total_qty,
                                          products.Product_Name,
                                          inv.date_created,
                                          uom.UOM_Name
                                    from tbl_invoice_products_void void
                                    inner join tbl_invoices inv on inv.Invoice_ID_Auto = void.Invoice_ID_Auto
                                    inner join tbl_stock_products products on products.Product_ID = void.Product_ID
                                    inner join tbl_stock_uom uom on uom.UOM_ID = void.UOM_ID
                                    where inv.date_created between "' . $open_time . '" AND "' . $close_time . '" 
                                    AND inv.current_year_id="' . $this->year_id . '" ' . $condition . '
                                    group by void.Product_ID,void.UOM_ID');
        while ($row = $this->db->assoc($query)) {
            $row['total_qty'] = CommonFunctions::formatNumber($row['total_qty']);
            $row['current_total_price'] = CommonFunctions::formatNumber($row['current_total_price']);
            $data[] = $row;
        }
        return $data;
    }

    public function getTotalDiscountedItems($open_time, $close_time) {
        $data = array();
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and inv.branch_id = "' . $this->info['branch_id'] . '" ';
        $query = $this->db->query('select sum(details.Product_Total_Price * inv.current_rate) as current_total_price,
                                          sum(details.Item_Quantity_Current) as total_qty,
                                          products.Product_Name,
                                          inv.date_created,
                                          uom.UOM_Name
                                    from tbl_invoice_products_details details
                                    inner join tbl_invoices inv on inv.Invoice_ID_Auto = details.Invoice_ID_Auto
                                    inner join tbl_stock_products products on products.Product_ID = details.Product_ID
                                    inner join tbl_stock_uom uom on uom.UOM_ID = details.UOM_ID
                                    where inv.date_created between "' . $open_time . '" AND "' . $close_time . '" 
                                    AND inv.current_year_id="' . $this->year_id . '" 
                                    and details.Discount_Amount != 0 ' . $condition . '
                                    group by details.Product_ID,details.UOM_ID');
        while ($row = $this->db->assoc($query)) {
            $row['total_qty'] = CommonFunctions::formatNumber($row['total_qty']);
            $row['current_total_price'] = CommonFunctions::formatNumber($row['current_total_price']);
            $data[] = $row;
        }
        return $data;
    }
    


    public function getTotalCreditCash($open_time, $close_time) {
        $data = array('total_cash' => 0, 'total_credit' => 0);
        $credit_accounts = array();
        $cash_accounts = array();
        $accounts = array();
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and branch_id = "' . $this->info['branch_id'] . '"';
        $account_query = $this->db->query("select * from tbl_chart_of_accounts where main_type = 'pay' and ( concat(',',sub_type,',') LIKE '%,cash,%'
        or concat(',',sub_type,',') LIKE '%,credit,%')");
        while ($row = $this->db->assoc($account_query)) {
            if ((strpos($row['sub_type'], 'cash') !== false) && (strpos($row['sub_type'], 'credit') === false)) {
                $cash_accounts[$row['Account_ID']] = $row['sub_type'];
            } else if ((strpos($row['sub_type'], 'credit') !== false)) {
                $credit_accounts[$row['Account_ID']] = $row['sub_type'];
            }
        }
        //        echo"<pre>";die(print_r($credit_accounts));
        if (!empty($credit_accounts)) {
            $account_credit_ids = implode(",", array_keys($credit_accounts));
            $credit_transaction_query = $this->db->query("select sum(if(Transaction_Type='Credit',local_amount*-1,local_amount)) total_credit from tbl_accounting_transactions where date_time between '" . $open_time . "' and '" . $close_time . "'  and Account_ID IN({$account_credit_ids})" . $condition);
            $row = $this->db->assoc($credit_transaction_query);
            $data['total_credit'] = $row['total_credit'];
        }
        if (!empty($cash_accounts)) {
            $account_cash_ids = implode(",", array_keys($cash_accounts));
            $cash_transaction_query = $this->db->query("select sum(if(Transaction_Type='Credit',local_amount*-1,local_amount)) as total_cash from tbl_accounting_transactions where date_time between '" . $open_time . "' and '" . $close_time . "'  and Account_ID IN({$account_cash_ids})" . $condition);
            $row = $this->db->assoc($cash_transaction_query);
            $data['total_cash'] = $row['total_cash'];
        }

        return $data;
    }

    public function getTotalCreditCashbyUser($open_time, $close_time,$user_id = null,$subtype = 'check') {
        $total_check = 0;
        $condition = '';
        if (!empty($this->info['branch_id']))
            $condition .= ' and branch_id = "' . $this->info['branch_id'] . '"';
        if(!empty($user_id))
            $condition .= ' and created_logged_id = "' . $user_id . '"';

        $check_query = $this->db->query("SELECT * FROM `tbl_accounting_transactions` WHERE subtype = '$subtype' and main_type = 'inv' and date_time between '" . $open_time . "' and '" . $close_time . "'  $condition");
         while ($row = $this->db->assoc($check_query)) {
                $total_check += $row['local_amount'];
        }
        //        echo"<pre>";die(print_r($credit_accounts));

        return $total_check;
    }


    //    public function get_end_of_shift_balances($open_time, $close_time, $currency_id, $user_id, $account_id) {
    //        $data = array();
    //        $total_cash = 0.0;
    //        $total_local_cash = 0.0;
    //        $local_currency = smc_session()['local_currency'];
    //        $cur_rate = CurrencyFactory::getLastExRate($currency_id);
    //        $net_inv_query = $this->db->query('select sum(if(' . $currency_id . '=' . $local_currency . ',Invoice_Net_Total,Invoice_Net_Total*current_rate/' . $cur_rate . ')) as amount,
    //            sum(Invoice_Net_Total*current_rate) as local_amount, concat(invoice_prefix,min(Invoice_ID)) as from_invoice,
    //             concat(invoice_prefix,max(Invoice_ID)) as to_invoice
    //            from tbl_invoices where Logged_ID = "' . $user_id . '"
    //                and STR_TO_DATE(date_time,"%Y-%m-%d %H:%i:%s" ) between "' . $open_time . '" and "' . $close_time . '" ');
    //        $inv_assoc = $this->db->assoc($net_inv_query);
    //        $data['totals']['net_invoices']['amount'] = !empty($inv_assoc['amount']) ? $inv_assoc['amount'] : 0;
    //        $data['totals']['net_invoices']['local_amount'] = !empty($inv_assoc['local_amount']) ? $inv_assoc['local_amount'] : 0;
    //        $data['totals']['net_invoices']['from_invoice'] = !empty($inv_assoc['from_invoice']) ? $inv_assoc['from_invoice'] : 0;
    //        $data['totals']['net_invoices']['to_invoice'] = !empty($inv_assoc['to_invoice']) ? $inv_assoc['to_invoice'] : 0;
    //
    //        $net_inv_query = $this->db->query('select sum(if(' . $currency_id . '=' . smc_session()['local_currency'] . ',Return_Net_Total,Return_Net_Total*current_rate/' . $cur_rate . ')) as amount,
    //            sum(Return_Net_Total*current_rate) as local_amount from tbl_accounting_return_invoices where Logged_ID = "' . $user_id . '"
    //                and STR_TO_DATE(date_time,"%Y-%m-%d %H:%i:%s" ) between "' . $open_time . '" and "' . $close_time . '"
    //
    //            ');
    //        $return_assoc = $this->db->assoc($net_inv_query);
    //        $data['totals']['net_returns']['amount'] = !empty($return_assoc['amount']) ? $return_assoc['amount'] : 0;
    //        $data['totals']['net_returns']['local_amount'] = !empty($return_assoc['local_amount']) ? $return_assoc['local_amount'] : 0;
    //        //
    //
    //        $types = array("deposit" => ["type" => "ddp", "op" => "+"],
    //                       "withdrawal" => ["type" => "dwd", "op" => "-"],
    //                       "payments" => ["type" => "pay", "op" => "-"],
    //                       "receipts" => ["type" => "rec", "op" => "+"],
    //                       "invoices" => ["type" => "inv", "op" => "+"],
    //                       "returns" => ["type" => "rin", "op" => "-"],
    //                       "expenses" => ["type" => "exp", "op" => "-"]);
    //        foreach ($types as $key => $type) {
    //            $query = $this->db->query('select sum(if(' . $currency_id . '=' . $local_currency . ',Transaction_Amount,Transaction_Amount*Current_Ex_Rate/' . $cur_rate . ')) as amount,
    //            sum(Transaction_Amount*Current_Ex_Rate) as local_amount
    //            from tbl_accounting_transactions where Account_ID = "' . $account_id . '" and Logged_ID="' . $user_id . '"
    //            and STR_TO_DATE(date_time,"%Y-%m-%d %H:%i:%s" ) between "' . $open_time . '" and "' . $close_time . '" and main_type ="' . $type['type'] . '" ');
    //            $data['totals'][$key] = $this->db->assoc($query);
    //            //$data[$key] = $this->get_type_balance_by_user($open_time, $close_time, $currency_id, $user_id, $cash_acc_id, $type['type']);
    //            $total_cash += $data['totals'][$key]['amount'] * ($type['op'] == '+' ? 1 : -1);
    //            $total_local_cash += $data['totals'][$key]['local_amount'] * ($type['op'] == '+' ? 1 : -1);
    //        }
    //        $data['totals']['total_cash']['amount'] = $total_cash;
    //        $data['totals']['total_cash']['local_amount'] = $total_local_cash;
    //        $data['open_time'] = $open_time;
    //        $data['close_time'] = $close_time;
    //        $data['currency_id'] = $currency_id;
    //        $data['currency_symbol'] = CurrencyFactory::getCurrencySymbol($currency_id);
    //        $data['username'] = User::get_username_by_id($user_id);
    //        return $data;
    //    }


    public function get_end_of_shift_by_id($id) {
        $query = $this->db->query('select * from tbl_end_of_shift where shift_id="' . $id . '"');
        $shift_row = $this->db->assoc($query);
        return $shift_row;
    }

    //    public function getPOSorderToPrint($id) {
    //        $data = array();
    //        $printers_id = array();
    //        $main_query = $this->db->query('SELECT * FROM pos_invoices WHERE Invoice_ID_Auto = "' . $id . '"');
    //        $main_arr = $this->db->assoc($main_query);
    //        $main_arr['printed_before_class'] = isset($this->info['printed_before']) ? '' : 'hidden';
    //        $main_arr['persons_count_class'] = $main_arr['Persons_Count'] != 0 ? '' : 'hidden';
    //        //$main_arr['order_time'] = $main_arr['Delivery_Time'] != "" ? $data['main_invoice']['Delivery_Time'] : date("h:i:s a");
    //        $main_arr['order_time'] = $main_arr['Is_Delivery'] == 0 ? $main_arr['date_time'] : $main_arr['Delivery_Time'];
    //        $main_arr['table_class'] = ($main_arr['Inv_Type'] == 2 && $main_arr['table_id'] != 0) ? '' : 'hidden';
    //        $main_arr['delivery_class'] = $main_arr['Inv_Type'] == 1 ? '' : 'hidden';
    //        $main_arr['note_class'] = !empty($main_arr['Invoice_Description']) ? '' : 'hidden';
    //        $main_arr['order_note_class'] = !empty($main_arr['order_note']) ? '' : 'hidden';
    //        $data['main_invoice'] = $main_arr;
    //        $tmp_items_arr = array();
    //        $item_ids_arr = array();
    //        $entry_ids_arr = array();
    //        $query = $this->db->query('SELECT p.Product_Name as Name,p.Product_Name,
    //                            d.Product_ID,
    //                            p.Printer_ID,d.Entery_ID,
    //                            concat(d.Product_ID,d.UOM_ID) as unq,
    //                            Product_Net_Price*conversion_amount as Product_Net_Price,
    //                            group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG,
    //                            (`Item_Quantity_Current`) as Item_Quantity_Current,
    //                            (`Product_Total_Price`) as `Product_Total_Price`,
    //                            Bar_Code,
    //                            d.product_description
    //                    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 `d`.`UOM_ID` = `u`.`UOM_ID`
    //                    inner join `tbl_uom_conversions` `uc` 
    //                    on d.Product_ID = `uc`.`Product_ID` and `d`.`UOM_ID` = `uc`.`uom_from`
    //                    left join tbl_invoice_product_criteria criteria using (`Entery_ID`) 
    //                    left join tbl_product_criteria_detail crit_detail using (`criteria_detail_id`) 
    //                    where d.`Invoice_ID_Auto` = "' . $id . '"
    //                    group by  `Entery_ID`');
    //
    //        while ($row = $this->db->assoc($query)) {
    //            $tmp_items_arr[$row['Entery_ID']] = $row;
    //            $tmp_items_arr[$row['Entery_ID']]['add_ons'] = '';
    //            $entry_ids_arr[] = $row['Entery_ID'];
    //            $item_ids_arr[$row['Product_ID']] = $row['Product_ID'];
    //        }
    //        $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.Printer_ID from tbl_products_link k 
    //                join tbl_stock_products p on p.Product_ID = k.sub_product_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;
    //            }
    //        }
    //
    //        foreach ($tmp_items_arr as $item_row) {
    //            $item_row['link_product_class'] = 'hidden';
    //            if (!empty($item_row['Printer_ID'])) {
    //                $printer_array = explode(",", $item_row['Printer_ID']);
    //                foreach ($printer_array as $printer_id) {
    //                    $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'] = $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['link_product_class'] = '';
    //                    $row_link['TAG'] = '';
    //                    $row_link['add_ons'] = '';
    //                    $row_link['Product_Net_Price'] = '--';
    //                    $row_link['Product_Total_Price'] = '--';
    //                    $row_link['Bar_Code'] = '--';
    //                    //$row_link['Printer_ID'] = $row_link['Printer_ID'];
    //                    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;
    //                            }
    //                        }
    //                    }
    //                }
    //            }
    //        }
    //        $data['printer_ids'] = $printers_id;
    //        return $data;
    //    }

    public function get_customer_invoices($customer_id, $from_date, $to_date, $with_keys = 0, $pos_customer = 0, $is_actual = null, $created_user = null, $search_branch_id_for_inv_cus = '') {
        $data = array('details' => array());
        $cond = '';
        if (!is_null($is_actual))
            $cond .= ' and is_actual = "' . $is_actual . '" ';
        if (!empty($pos_customer))
            $cond .= ' and pos_customer_id = "' . $pos_customer . '"';
        if (!empty($created_user))
            $cond .= ' and i.created_logged_id = "' . $created_user . '"';

        if($this->permissions->hasPermission('Branches')){
            $cond .= !empty($search_branch_id_for_inv_cus) ? ' and i.branch_id ="' . ($search_branch_id_for_inv_cus) . '"' : '';
        }else{
            $cond .= ' and i.branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
        }
            
        $query = $this->db->query('select concat(invoice_prefix,Invoice_ID) as invoice_nb,
            Invoice_Date,(Invoice_Net_Total+Invoice_Shipping) as Invoice_Net_Total,(Invoice_Paid_Amount+Payment_Paid_Amount) as paid_amount,
            current_rate,cu.Currency_Symbol from tbl_invoices i join tbl_common_currency cu on cu.Currency_ID = i.Invoice_Currency where Customer_ID = "' . $customer_id . '"
                and Invoice_Date between "' . $from_date . '" and "' . $to_date . '" ' . $cond);
        $total = 0;
        $total_paid = 0;
        while ($row = $this->db->assoc($query)) {
            $total += CommonFunctions::public_round_number($row['Invoice_Net_Total'] * $row['current_rate']);
            $total_paid += ($row['paid_amount'] * $row['current_rate']);
            $row['Invoice_Net_Total'] = CommonFunctions::public_round_number($row['Invoice_Net_Total']) . ' ' . $row['Currency_Symbol'];
            $row['paid_amount'] = CommonFunctions::public_round_number($row['paid_amount']) . ' ' . $row['Currency_Symbol'];
            unset($row['current_rate']);
            unset($row['Currency_Symbol']);
            $data['details'][] = $with_keys ? $row : array_values($row);
        }
        $data['total'] = CommonFunctions::public_round_number($total) . ' ' . smc_session()['local_currency_symbol'];
        $data['total_paid'] = CommonFunctions::public_round_number($total_paid) . ' ' . smc_session()['local_currency_symbol'];
        $data['total_unpaid'] = CommonFunctions::public_round_number($total - $total_paid) . ' ' . smc_session()['local_currency_symbol'];
        $person = Customer::getCustomerByID($customer_id);
        return array_merge($data, $person);
    }

    public function customer_ledger($customer_id, $from_date, $to_date, $with_keys = 0, $ignore_zero = 0, $is_actual = null, $pos_cust_id = 0, $search_branch_id_for_ledger = '') {
        $data = array('details' => array());
        $account_id = self::getCustomerAccount($customer_id)['Account_ID'];
        $cond = ' ';
        if (!is_null($is_actual))
            $cond .= ' and is_actual = "' . $is_actual . '" ';
        if (!empty($pos_cust_id))
            $cond .= ' and pos_customer_id = "' . $pos_cust_id . '" ';

        if($this->permissions->hasPermission('Branches')){
            $cond .= !empty($search_branch_id_for_ledger) ? ' and t.branch_id ="' . ($search_branch_id_for_ledger) . '"' : '';
        }else{
            $cond .= ' and t.branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;
        }
            
        $query = $this->db->query('select main_type,concat(prefix,main_nb) as main_nb,Transaction_Date,Transaction_Amount,
            Transaction_Type,Current_Ex_Rate,cu.Currency_Symbol,local_amount,t.second_currency_rate
            from tbl_accounting_transactions t
            join tbl_common_currency cu on cu.Currency_ID = t.Currency_ID
            where Account_ID = "' . $account_id . '"
            and Transaction_Date between "' . $from_date . '" and "' . $to_date . '" ' . $cond);
        $balance = 0;
        $second_balance = 0;
        while ($row = $this->db->assoc($query)) {
            $balance += ($row['local_amount'] * ($row['Transaction_Type'] == 'Credit' ? -1 : 1));
            $second_balance += ($row['Transaction_Amount'] * $row['second_currency_rate'] * ($row['Transaction_Type'] == 'Credit' ? -1 : 1));
            if ($row['main_type'] == 'inv' && $row['Transaction_Type'] == 'Credit')
                $row['main_type'] = CommonBusiness::get_trans_main_type('rec') . ' (Invoice)';
            else
                $row['main_type'] = CommonBusiness::get_trans_main_type($row['main_type']);
            $row['Transaction_Amount'] = CommonFunctions::formatNumber($row['Transaction_Amount'] * ($row['Transaction_Type'] == 'Credit' ? -1 : 1)) . ' ' . $row['Currency_Symbol'];
            unset($row['Current_Ex_Rate']);
            unset($row['local_amount']);
            unset($row['Currency_Symbol']);
            unset($row['Transaction_Type']);
            unset($row['second_currency_rate']);
            $data['details'][] = $with_keys ? $row : array_values($row);
            if ($balance == 0 && $ignore_zero == 1) {
                $data['details'] = array();
            }
        }
        $second_currency_balance = smc_session()['default_setting']['activate_second_currency'] == 1 ?  ' <br> Second balance :' . CommonFunctions::formatNumber($second_balance) . ' ' . smc_session()['second_currency']['symbol'] : '';
        $data['balance'] = 'Local balance :' . CommonFunctions::formatNumber($balance) . ' ' . smc_session()['local_currency_symbol'].$second_currency_balance ;
        $person = Customer::getCustomerByID($customer_id);
        return array_merge($data, $person);
    }

    public function getCustomerLastOrders() {
        $condition = '';
        $data = $current_ids = array();
        if ($this->info['customer_is_pos'] == 1) {
            $condition .= 'and pos_customer_id = "' . $this->info['pos_customer_id'] . '" ';
        } else {
            $condition .= 'and Person_ID = "' . $this->info['Customer_ID'] . '" ';
        }
        $orders_query = $this->db->query('select * from invoice_list where 1=1 ' . $condition . ' order by date_created desc limit ' . $this->info['limit'] . ' ');
        while ($row = $this->db->assoc($orders_query)) {
            $data[$row['ID_Auto']] = ["current_date" => $row['date_created'], "inv_num" => $row['ID'], "cur_symbol" => $row['Currency_Symbol'], "items" => []];
            $current_ids[] = $row['ID_Auto'];
        }
        if (!empty($current_ids)) {
            $items_query = $this->db->query('SELECT *, concat(Product_ID,UOM_ID) as unq,
                            Product_Net_Price*conversion_amount as Product_Net_Price,
                            group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG
                    FROM invoice_details 
                    left join tbl_invoice_product_criteria criteria using (`Entery_ID`) 
                    left join tbl_product_criteria_detail crit_detail using (`criteria_detail_id`) 
                    where `Invoice_ID_Auto` IN (' . implode(",", $current_ids) . ')
                    group by  `Entery_ID`');
            while ($row = $this->db->assoc($items_query)) {
                $data[$row['Invoice_ID_Auto']]["items"][] = ["TAG" => $row['TAG'], "Name" => $row["Name"],
                    "Item_Quantity_Current" => $row["Item_Quantity_Current"] . ' ' . $row["UOM_Name"], "Product_Net_Price" => CommonFunctions::formatNumber($row['Product_Net_Price'])];
            }
        }
        return $data;
    }

    public function get_postponed_report() {
        $cond = '';
        $data = array();
        if (isset($this->info['customer_id']) && $this->info['customer_id'] != '') {
            $cond .= ' and inv.Customer_ID = "' . $this->info['customer_id'] . '"';
        }
        if (isset($this->info['pos_customer']) && $this->info['pos_customer'] != '') {
            $cond .= ' and inv.pos_customer_id = "' . $this->info['pos_customer'] . '"';
        }
        if (!empty($this->info['inv_list_nb'])) {
            $cond .= ' and concat_ws("",invoice_prefix,Invoice_ID) = "' . $this->info['inv_list_nb'] . '"';
        }
        if (!empty($this->info['posponted_status'])) {
            $cond .= ' and inv.posponted_type = "' . $this->info['posponted_status'] . '"';
        }
        if (!empty($this->info['branch_id'])) {
            $cond .= ' and inv.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(inv.postponed_date_time) between  "' . $this->info['postponed_date_from'] . '"  and  "' . $this->info['postponed_date_to'] . '"';
        }
        $cond .= ' and inv.is_actual ="' . $this->info['is_actual'] . '"';
        $orders_query = $this->db->query('select 
                                                 inv.Customer_ID,
                                                 inv.pos_customer_id,
                                                 concat_ws("",invoice_prefix,Invoice_ID) as ID,
                                                 if(isnull(inv.pos_customer_id) or inv.pos_customer_id =0,customers.Customer_Name,pos_cust.customer_name) AS Name,
                                                 inv.postponed_date_time,
                                                 inv.postponed_note,
                                                 inv.posponted_type,
                                                 category.Cat_Name,
                                                 products.Product_Name,
                                                 products.Category_ID,
                                                 details.Item_Quantity_Current,
                                                 details.Entery_ID
                                          from tbl_invoices inv
                                          inner join tbl_invoice_products_details details using(Invoice_ID_Auto)
                                          inner join tbl_stock_products products on products.Product_ID = details.Product_ID
                                          inner join tbl_product_cat category on category.Cat_ID = products.Category_ID
                                          inner join tbl_customers customers on customers.Customer_ID = inv.Customer_ID
                                          left join tbl_pos_customers pos_cust on inv.pos_customer_id = pos_cust.customer_id
                                          where inv.invoice_type=5 
                                          and inv.current_year_id = "' . $this->year_id . '" and  inv.posponted_type <> 0
                                          ' . $cond . '
                                           group by  details.Entery_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['Entery_ID']] = $row['Category_ID'];
            $entry_ids.=(empty($entry_ids) ? '' : ',') . $row['Entery_ID'];
            $data[$row['Category_ID']]['details'][$row['Entery_ID']] = ['invoice_nb' => $row['ID'],
                'customer_name' => $row['Name'],
                'postponed_date_time' => $row['postponed_date_time'],
                'postponed_note' => $row['postponed_note'],
                '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.Entery_ID,
                    criteria_main.criteria_name,criteria.criteria_note,
                    group_concat(crit_detail.criteria_detail_name SEPARATOR ",") as TAG
             from tbl_invoice_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.Entery_ID in (' . $entry_ids . ')
              group by criteria.Entery_ID,crit_detail.criteria_id');
            while ($row = $this->db->assoc($query)) {
                $tag = $data[$cat_detail_arr[$row['Entery_ID']]]['details'][$row['Entery_ID']]['tag'];
                $data[$cat_detail_arr[$row['Entery_ID']]]['details'][$row['Entery_ID']]['tag'].=(empty($tag) ? '' : '<br>') . ($row['criteria_name'] . ': ' . $row['TAG']);
                $data[$cat_detail_arr[$row['Entery_ID']]]['details'][$row['Entery_ID']]['criteria_note'] = $row['criteria_note'];
                $data[$cat_detail_arr[$row['Entery_ID']]]['details'][$row['Entery_ID']]['criteria_name'] = $row['criteria_name'];
            }
        }
        return $data;
    }

    public function insertOpenDrawerReason($open_reason) {
        $date_time = date('Y-m-d H:i:s');
        $user_id = smc_session()['user_logged_id'];
        $data = [&$open_reason, &$user_id, &$date_time];
        $this->db->prepare_Stmt('insert into tbl_open_drawer (open_reason,user_id,date_time) values (?,?,?)', $data);
        $error = $this->db->error();
        return $error;
    }

    public function add_exchange($exchange_arr) {
        //        die('here');
        $this->db->query('START TRANSACTION');
        $inv_arr = array();
        $ret_arr = array();
        $ret_id = 0;
        $inv_id = 0;
        $inv_sub_total = 0;
        $ret_sub_total = 0;
        $inv_net_total = 0;
        $ret_net_total = 0;
        $inv_paid_total = 0;
        $ret_paid_total = 0;
        $inv_vat_total = 0;
        $ret_vat_total = 0;
        $inv_vat1_total = 0;
        $ret_vat1_total = 0;
        $inv_vat2_total = 0;
        $ret_vat2_total = 0;
        $return_discount = 0;
        $invoice_discount = 0;
        foreach ($exchange_arr['products'] as $item) {

            if ($item['Product_Quantity'] < 0) {
                $item['vat_amount'] = abs($item['vat_amount']);
                $item['vat2_amount'] = abs($item['vat2_amount']);
                $item['Product_Quantity'] = abs($item['Product_Quantity']);
                $item['Total_Price'] = abs($item['Total_Price']);
                $item['Return_Product_Total'] = abs($item['Return_Product_Total']);
                //                echo 'ret=='.$item['Item_Price'].'==='.$item['Product_Quantity'].'==='.$item['Discount_Amount'];

                $ret_net_total += $item['Return_Product_Total'];
                $ret_sub_total += (($item['Item_Price'] - abs($item['disc_amt_noqty'])) * abs($item['Product_Quantity']) );
                $ret_vat1_total += $item['vat_amount'];
                $ret_vat2_total += $item['vat2_amount'];
                $ret_vat_total += ($item['vat_amount'] + $item['vat2_amount']);
                $ret_arr[] = $item;
            } else {
                //                echo 'inv=='.$item['Item_Price'].'==='.$item['Product_Quantity'].'==='.$item['Discount_Amount'];
                //                echo $item['Total_Price'].'===';

                $inv_net_total += $item['Total_Price'];
                $inv_sub_total += (($item['Item_Price'] * $item['Product_Quantity']) - $item['Discount_Amount']);
                $inv_vat1_total += $item['vat_amount'];
                $inv_vat2_total += $item['vat2_amount'];
                $inv_vat_total += ($item['vat_amount'] + $item['vat2_amount']);
                $inv_arr[] = $item;
            }
        }
        //         die();
        $return_discount = abs($ret_sub_total) * $exchange_arr['Invoice_Discount'] / 100;
        $invoice_discount = abs($inv_sub_total) * $exchange_arr['Invoice_Discount'] / 100;

        $ret_net_total = $ret_net_total + $ret_vat_total;
        //        $inv_net_total = $inv_net_total + $inv_vat_total;
        $ret_paid_total = $ret_net_total;
        $paid_total = $exchange_arr['Paid_Amount'];
        if (!empty($ret_arr)) {
            //            die('here');
            $exchange_arr['products'] = $ret_arr;
            $this->stop_transaction_start_end = true;
            $exchange_arr['cash_amount'] = $paid_total < 0 ? abs($paid_total) : 0;
            $exchange_arr['Invoice_Sub_Total'] = abs($ret_sub_total);
            $exchange_arr['Invoice_Net_Total'] = abs($ret_net_total);
            $exchange_arr['Invoice_VAT'] = abs($ret_vat_total);
            $exchange_arr['vat1_total'] = abs($ret_vat1_total);
            $exchange_arr['vat2_total'] = abs($ret_vat2_total);
            $exchange_arr['Discount_Amount'] = abs($return_discount);
            //            echo"<pre>";die(print_r($exchange_arr));
            //              echo $ret_vat_total.'===='.$ret_net_total.'===='.$exchange_arr['Invoice_Discount'];
            //        die();
            $RET = $this->setdata($exchange_arr)->posReturn();
            $ret_id = !is_array($RET) ? $RET : 0;
        }

        if (!empty($inv_arr)) {
            //            die('heree');
            $exchange_arr['products'] = $inv_arr;
            $this->stop_transaction_start_end = true;
            $exchange_arr['cash_amount'] = $paid_total > 0 ? abs($paid_total) : 0;
            $exchange_arr['Paid_Amount'] = $paid_total > 0 ? abs($paid_total) : 0;
            $exchange_arr['Invoice_Sub_Total'] = $inv_sub_total;
            $exchange_arr['Invoice_Net_Total'] = $inv_net_total;
            $exchange_arr['Invoice_VAT'] = $inv_vat_total;
            $exchange_arr['vat1_total'] = abs($inv_vat1_total);
            $exchange_arr['vat2_total'] = abs($inv_vat2_total);
            $exchange_arr['Discount_Amount'] = abs($invoice_discount);
            //                          echo $inv_vat_total.'===='.$inv_net_total.'===='.$exchange_arr['Invoice_Discount'];
            //die();
            //             echo"<pre>";die(print_r($exchange_arr));
            $RET = $this->setdata($exchange_arr)->createPOS();
            $inv_id = !is_array($RET) ? $RET : 0;
        }
        //        $error = $this->db->error();
        //        die(print_r($error));
        if (!empty($ret_arr) && !empty($inv_arr)) {
            //            $exchange_arr = array(
            //                "invoice_auto_id" => $inv_id,
            //                "return_auto_id" => $ret_id,
            //                "is_actual" => 0
            //            );
            $prefix = smc_session()['user_accounts']['serial_prefix'];
            $exchange_nb = $this->getMaxExchange($prefix, 0);
            //            echo $prefix.'==';
            $today = Date::getToday();
            $mydate = date("y-m-d H:i:s");
            $logged_id = smc_session()['user_logged_id'];
            $is_actual = $exchange_arr['is_actual'];
            $data = [&$exchange_nb, &$prefix, &$today, &$inv_id,
                &$ret_id, &$is_actual, &$mydate, &$mydate, &$logged_id, &$logged_id, &$this->year_id];
            $this->db->prepare_Stmt('INSERT INTO `tbl_exchange`( `exchange_nb`, `exchange_prefix`,
            `exchange_date`, `invoice_auto_id`, `return_auto_id`, `is_actual`, `date_created`, `date_time`,
            `Logged_ID`, `created_logged_id`,current_year_id) values(?,?,?,?,?,?,?,?,?,?,?)', $data);
            $exchange_id = $this->db->id();
            $this->db->prepare_Stmt('update tbl_invoices set exchange_id = ? where Invoice_ID_Auto=?', [&$exchange_id, &$inv_id]);
            $this->db->prepare_Stmt('update tbl_accounting_return_invoices set exchange_id = ? where Return_Invoice_ID=?', [&$exchange_id, &$ret_id]);
            //
        }
        $error = $this->db->error();
        /* if (empty($error)){
          if (!empty($ret_arr) && !empty($inv_arr)) {
          if (empty($error) && smc_session()['default_setting']['sumatra_print'] == 1) {
          $data_arr = $this->get_exchange_by_id($exchange_id);
          $template_row = Forms::build_print_template('pos_exchange', $data_arr['main'], array('inv_detail' => $data_arr['inv_detail'], 'ret_detail' => $data_arr['ret_detail']));
          $print_w_h = Forms::get_print_width_height('pos');
          $filename = Forms::html2pdf($template_row['html'], $print_w_h);
          Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
          }
          }elseif (!empty($ret_arr)){
          $this->posInvPOS($ret_id);
          }
          else{
          $this->posInvPOS($inv_id);
          }
          } */
        if (empty($error)) {
            $this->db->query("COMMIT");
            return empty($exchange_id) ? ((empty($inv_id) && !empty($ret_id)) ? [$ret_id, 'return'] : [$inv_id, 'invoice'] ) : [$exchange_id, 'exchange'];
        } else {
            $this->db->query('ROLLBACK');
            return $error;
        }
    }

    public function getMaxExchange($prefix, $is_actual) {

        $yearid = $is_actual ? $this->year_id_actual : $this->year_id;
        $query = $this->db->query('SELECT MAX(exchange_nb) AS Entry_ID 
            FROM tbl_exchange where current_year_id = "' . $yearid . '" '
                . 'and exchange_prefix = "' . $prefix . '" and is_actual = "' . $is_actual . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $exchange = $row['Entry_ID'] + 1;
        else
            $exchange = 1;

        return $exchange;
    }

    public function get_exchange_by_id($id) {
        $data = array();
        $total_inv = $total_ret = 0.0;
        //
        $query = $this->db->query('select * from tbl_exchange where exchange_id = "' . $id . '"');
        $data['main'] = $this->db->assoc($query);
        //
        $query_inv_main = $this->db->query('select * from tbl_invoices where Invoice_ID_Auto = "' . $data['main']['invoice_auto_id'] . '"');
        $inv_main = $this->db->assoc($query_inv_main);
        $total_inv = $inv_main['Invoice_Net_Total'] + $inv_main['Invoice_Shipping']; //note no shipping from exchange | since no delivery
        $data['main']['Invoice_Description'] = $inv_main['Invoice_Description'];
        //
        $query_ret_main = $this->db->query('select * from tbl_accounting_return_invoices where Return_Invoice_ID = "' . $data['main']['return_auto_id'] . '"');
        $ret_main = $this->db->assoc($query_ret_main);
        $total_ret = $ret_main['Return_Net_Total'];
        //
        if (!empty($data['Main']['pos_customer_id']))
            $person = Customer::getPOSCustomerByID($inv_main['pos_customer_id']);
        else
            $person = Customer::getCustomerByID($inv_main['Customer_ID']);
        //
        $data['main'] = array_merge($data['main'], $person);
        //
        $query_inv = $this->db->query('select
                                                i.Entery_ID AS Entery_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.Status_ID,
                                                if(i.vat_percent <> 0,1,0) AS VAT,
                                                i.Product_ID AS Product_ID,
                                                i.vat_percent,
                                                i.vat_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,0 as is_damaged
                                            from 
                                                tbl_invoice_products_details i 
                                            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

                                            where

                                                i.Invoice_ID_Auto = "' . $data['main']['invoice_auto_id'] . '"');
        while ($row_inv = $this->db->assoc($query_inv)) {
            $row_inv['Product_Net_Price_TTC'] = $row_inv['Product_Net_Price'] * (1 + ($row_inv['vat_percent'] / 100));
            $row_inv['Product_Net_Price_After_Disc'] = $row_inv['Product_Net_Price'] * (1 - ($row_inv['Product_Discount'] / 100));
            $row_inv['Product_Net_Price_After_Disc_TTC'] = $row_inv['Product_Net_Price_After_Disc'] * (1 + ($row_inv['vat_percent'] / 100));
            $row_inv['Product_Total_Price_After_Disc'] = $row_inv['Product_Net_Price_After_Disc'] * $row_inv['Item_Quantity_Current'];
            $row_inv['Product_Total_Price_After_Disc_TTC'] = $row_inv['Product_Net_Price_After_Disc_TTC'] * $row_inv['Item_Quantity_Current'];
            //$total_inv += $row_inv['Product_Total_Price_After_Disc_TTC'];
            $row_inv['Product_Net_Price'] = CommonFunctions::formatNumber($row_inv['Product_Net_Price']);  //unit price without vat and before disc.
            $row_inv['Product_Net_Price_TTC'] = CommonFunctions::formatNumber($row_inv['Product_Net_Price_TTC']);  //ttc unit price with vat and before disc.
            $row_inv['Product_Net_Price_After_Disc'] = CommonFunctions::formatNumber($row_inv['Product_Net_Price_After_Disc']);  //unit price after product disc. & before no inv. disc
            $row_inv['Product_Net_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($row_inv['Product_Net_Price_After_Disc_TTC']);  //ttc unit price with vat and after product disc. & before inv. disc
            $row_inv['Product_Total_Price_After_Disc'] = CommonFunctions::formatNumber($row_inv['Product_Total_Price_After_Disc']);  //total price after product disc. & before no inv. disc
            $row_inv['Product_Total_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($row_inv['Product_Total_Price_After_Disc_TTC']);  //ttc total price with vat and after product disc. & before inv. disc
            $row_inv['is_damaged_class'] = 'hidden';
            $data['inv_detail'][] = $row_inv;
        }
        $query_ret = $this->db->query('select
                                                i.Item_Quantity_Current AS Item_Quantity_Current,
                                                ps.Product_Code AS Code,
                                                ps.Product_Name AS Name,
                                                ps.is_tax,
                                                if(i.vat_percent <> 0,1,0) VAT,
                                                i.vat_percent,
                                                i.vat_amount,
                                                ps.Product_Quantity,
                                                i.Product_ID AS Product_ID,
                                                i.Product_Discount AS Product_Discount,
                                                i.product_description,
                                                i.unit_price AS Product_Net_Price,
                                                i.Return_Product_Total AS Product_Total_Price,
                                                (i.Return_Product_Quantity/i.Item_Quantity_Current) AS uom_con,
                                                 i.UOM_ID,
                                                 uc.Bar_Code,i.expiry_date,ps.is_expiry,
                                                GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                                ps.Status_ID,i.is_damaged
                                            from 
                                                tbl_accounting_return_items i 

                                            LEFT JOIN
                                                uom_conversions uc
                                            ON 
                                                uc.Product_ID = i.Product_ID
                                            left join 
                                                tbl_stock_products ps 
                                            on
                                                ps.Product_ID = i.Product_ID
                                            where
                                                i.Return_Invoice_ID = "' . $data['main']['return_auto_id'] . '"
                                            GROUP BY i.Return_Item_ID

                                            ');
        while ($row_ret = $this->db->assoc($query_ret)) {
            $row_ret['Product_Net_Price_TTC'] = $row_ret['Product_Net_Price'] * (1 + ($row_ret['vat_percent'] / 100));
            $row_ret['Product_Net_Price_After_Disc'] = $row_ret['Product_Net_Price'] * (1 - ($row_ret['Product_Discount'] / 100));
            $row_ret['Product_Net_Price_After_Disc_TTC'] = $row_ret['Product_Net_Price_After_Disc'] * (1 + ($row_ret['vat_percent'] / 100));
            $row_ret['Product_Total_Price_After_Disc'] = $row_ret['Product_Net_Price_After_Disc'] * $row_ret['Item_Quantity_Current'];
            $row_ret['Product_Total_Price_After_Disc_TTC'] = $row_ret['Product_Net_Price_After_Disc_TTC'] * $row_ret['Item_Quantity_Current'];
            //$total_ret += $row_ret['Product_Total_Price_After_Disc_TTC'];
            $row_ret['Product_Net_Price'] = CommonFunctions::formatNumber($row_ret['Product_Net_Price']);  //unit price without vat and before disc.
            $row_ret['Product_Net_Price_TTC'] = CommonFunctions::formatNumber($row_ret['Product_Net_Price_TTC']);  //ttc unit price with vat and before disc.
            $row_ret['Product_Net_Price_After_Disc'] = CommonFunctions::formatNumber($row_ret['Product_Net_Price_After_Disc']);  //unit price after product disc. & before no inv. disc
            $row_ret['Product_Net_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($row_ret['Product_Net_Price_After_Disc_TTC']);  //ttc unit price with vat and after product disc. & before inv. disc
            $row_ret['Product_Total_Price_After_Disc'] = CommonFunctions::formatNumber($row_ret['Product_Total_Price_After_Disc']);  //total price after product disc. & before no inv. disc
            $row_ret['Product_Total_Price_After_Disc_TTC'] = CommonFunctions::formatNumber($row_ret['Product_Total_Price_After_Disc_TTC']);  //
            $row_ret['is_damaged_class'] = $row_ret['is_damaged'] ? '' : 'hidden';
            $data['ret_detail'][] = $row_ret;
        }
        $data['main']['total_invoice'] = CommonFunctions::formatNumber($total_inv);
        $data['main']['total_return'] = CommonFunctions::formatNumber($total_ret);
        $data['main']['total_cash'] = CommonFunctions::formatNumber($total_inv - $total_ret);
        return $data;
        //            echo"<pre>";die(print_r($data));
    }

    public function delete_exchange($id) {
        $this->db->query('START TRANSACTION');
        $query = $this->db->query('select * from tbl_exchange where exchange_id = "' . $id . '"');
        $row = $this->db->assoc($query);
        $ret_id = $row['return_auto_id'];
        $inv_id = $row['invoice_auto_id'];
        $invoice = new Invoice;
        $invoice->stop_transaction_start_end = true;
        $invoice->deleteSalesInvoice([$inv_id]);
        $return = new ReturnInvoice;
        $return->stop_transaction_start_end = true;

        $return->deleteReturn([$ret_id], true);
        $this->db->prepare_Stmt('delete from tbl_exchange where exchange_id = ?', [&$id]);
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function retreive_exchange_by_id($id) {
        $data = array("Details" => array());
        $year = SESSION::getCurrentYearID();
        $entry_ids_array = array();
        $entry_ids_str = '';
        $query = $this->db->query('select * from tbl_exchange where exchange_id = "' . $id . '"');
        $ex_data = $this->db->assoc($query);
        $inv_id = $ex_data['invoice_auto_id'];
        $ret_id = $ex_data['return_auto_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
          from invoice_list_main where Invoice_ID_Auto = "' . smc_escape($inv_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'] = '';
        $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;

        if (!empty($data['Main']['pos_customer_id'])) {
            $data['Person'] = Customer::getPOSCustomerByID($data['Main']['pos_customer_id']);
        } else {
            $data['Person'] = Customer::getCustomerByID($data['Main']['Customer_ID']);
        }
        $query_details = $this->db->query('select
                                                i.Entery_ID AS Entery_ID,
                                                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.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.vat2_amount,
                                                i.vat_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.lot_nb,i.serial_nb,
                                                 ps.is_service,
                                                 0 as is_damaged
                                            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 = p.Depot_ID
                                            where
                                                p.current_year_id = "' . $year . '"
                                            and 
                                                p.Invoice_ID_Auto = "' . $inv_id . '"
                                            order by p.Invoice_ID');
        $product_entry_ids = array();
        while ($row = $this->db->assoc($query_details)) {
            $product_entry_ids[$row['Product_ID']][] = $row['Entery_ID'];
            $row['ttc_price'] = $row['Product_Net_Price'] * (1 + ($row['vat_percent'] / 100));
            $row['Product_UOM'] = '';
            $data['Details'][$row['Entery_ID']] = $row;
            //            $entry_ids_array[] = $row['Entery_ID'];
        }
        $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'];
            }
        }
        $query_details = $this->db->query('select
                                                i.Return_Item_ID AS Entery_ID,
                                                p.Return_Invoice_ID 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.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.vat_amount,i.vat2_percent,i.vat2_amount,
                                                i.unit_cost,
                                                i.product_description,
                                                uc.Bar_Code,
                                                i.Product_Discount AS Product_Discount,
                                                i.unit_price AS Product_Net_Price,
                                                i.Return_Product_Total AS Product_Total_Price,
                                                (i.Return_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.lot_nb,i.serial_nb,
                                                 i.is_damaged
                                            from 
                                                tbl_accounting_return_items i 
                                            inner join 
                                                tbl_accounting_return_invoices p 
                                            on
                                                p.Return_Invoice_ID = i.Return_Invoice_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 = p.Depot_ID
                                            where
                                                p.current_year_id = "' . $year . '"
                                            and 
                                                p.Return_Invoice_ID = "' . $ret_id . '"
                                            order by p.Return_ID');
        $product_entry_ids = array();
        while ($row = $this->db->assoc($query_details)) {
            $product_entry_ids[$row['Product_ID']][] = 'ret' . $row['Entery_ID'];
            $row['ttc_price'] = $row['Product_Net_Price'] * (1 + ($row['vat_percent'] / 100));
            $row['Item_Quantity_Current'] = $row['Item_Quantity_Current'] * -1;
            $row['Product_UOM'] = '';
            $data['Details']['ret' . $row['Entery_ID']] = $row;
            //            $entry_ids_array[] = $row['Entery_ID'];
        }
        $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'];
            }
        }
        $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
                                        FROM 
                                            tbl_accounting_transactions t
                                        LEFT JOIN 
                                            tbl_chart_of_accounts p
                                        ON 
                                            t.Account_ID = p.Account_ID
                                       WHERE 
                                             t.main_id = '" . $inv_id . "'
                                        AND 
                                            t.main_type = 'inv'
                                        AND 
                                            t.Transaction_Reference in ('cash','check','credit')
                                        ");
        $data['Payment'] = array();
        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;
        }
        //                            echo"<pre>";
        //                            die(print_r($data));
        return $data;
    }

    public function edit_exchange($exchange_arr) {
        //                    echo"<pre>";die(print_r($exchange_arr));

        $this->db->query('START TRANSACTION');
        $inv_arr = array();
        $ret_arr = array();
        $ret_id = 0;
        $inv_id = 0;
        $inv_sub_total = 0;
        $ret_sub_total = 0;
        $inv_net_total = 0;
        $ret_net_total = 0;
        $inv_paid_total = 0;
        $ret_paid_total = 0;
        $ret_vat_total = 0;
        $inv_vat_total = 0;
        $inv_vat1_total = 0;
        $ret_vat1_total = 0;
        $inv_vat2_total = 0;
        $ret_vat2_total = 0;
        $return_discount = 0;
        $invoice_discount = 0;
        $query = $this->db->query('select e.*,i.Depot_ID from tbl_exchange e join tbl_invoices i on i.exchange_id = e.exchange_id
            where e.exchange_id = "' . $exchange_arr['ex_id'] . '"');
        $row_ex = $this->db->assoc($query);
        $ret_id = $row_ex['return_auto_id'];
        $inv_id = $row_ex['invoice_auto_id'];
        foreach ($exchange_arr['products'] as $item) {
            $item['Entery_ID'] = 0;
            if ($item['Product_Quantity'] < 0) {
                $item['Product_Quantity'] = abs($item['Product_Quantity']);
                $item['Return_Product_Quantity'] = abs($item['Product_Quantity']);
                //                $item['Return_Product_Total'] = abs($item['Total_Price']);
                $item['Total_Price'] = abs($item['Total_Price']);
                $item_total_price = abs($item['Return_Product_Total']);
                $item['Return_Product_Total'] = $item_total_price;
                $item['vat_amount'] = abs($item['vat_amount']);
                $item['vat_val'] = $item['vat_amount'];
                $item['Unit_Cost'] = abs($item['Net_Price']);
                $item['Item_Discount'] = abs($item['Product_Disc']);
                $item['purchase_detail_id'] = 0;
                $ret_net_total += ($item_total_price + abs($item['vat_amount']));
                $ret_sub_total += (($item['Item_Price'] - abs($item['disc_amt_noqty'])) * abs($item['Product_Quantity']) );
                $ret_vat1_total += $item['vat_amount'];
                $ret_vat2_total += $item['vat2_amount'];
                $ret_vat_total += ($item['vat_amount'] + $item['vat2_amount']);
                $ret_arr[] = $item;
            } else {
                $item['Item_Quantity'] = abs($item['Product_Quantity']);
                $inv_net_total += $item['Total_Price'];
                $inv_sub_total += (($item['Item_Price'] * $item['Product_Quantity']) - $item['Discount_Amount']);
                $inv_vat1_total += $item['vat_amount'];
                $inv_vat2_total += $item['vat2_amount'];
                $inv_vat_total += ($item['vat_amount'] + $item['vat2_amount']);
                $inv_arr[] = $item;
            }
        }
        $return_discount = abs($ret_sub_total) * $exchange_arr['Invoice_Discount'] / 100;
        $invoice_discount = abs($inv_sub_total) * $exchange_arr['Invoice_Discount'] / 100;

        //        $ret_net_total = $ret_net_total;
        //        $inv_net_total = $inv_net_total - $exchange_arr['Discount_Amount'];
        $ret_paid_total = $ret_net_total;
        $paid_total = $exchange_arr['Paid_Amount'];
        $delete_ex_flag = false;
        if (empty($ret_arr) || empty($inv_arr)) {
            $delete_ex_flag = true;
            $this->db->prepare_Stmt('delete from tbl_exchange where exchange_id = ?', [&$exchange_arr['ex_id']]);
        }
        $return = new ReturnInvoice();
        $return->stop_transaction_start_end = true;
        if (empty($ret_arr)) {
            $return->deleteReturn([$ret_id], true);
        } else {
            if ($delete_ex_flag)
                $this->db->prepare_Stmt('update tbl_accounting_return_invoices set exchange_id = null where Return_Invoice_ID=?', [&$ret_id]);
            $exchange_arr['Return_Invoice_Date'] = $row_ex['exchange_date'];
            $exchange_arr['Currency_ID'] = $exchange_arr['Invoice_Currency'];
            $exchange_arr['Is_Customer_Invoice'] = 1;
            $exchange_arr['Return_ID'] = $ret_id;
            $exchange_arr['date_time'] = $row_ex['date_time'];
            $exchange_arr['Is_Actual'] = $row_ex['is_actual'];
            $exchange_arr['Depot_ID'] = smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'];
            $exchange_arr['Card_Amount'] = 0;
            $exchange_arr['Card_Account'] = '';
            $exchange_arr['Cash_Amount'] = $paid_total < 0 ? abs($paid_total) : 0;
            $exchange_arr['Cash_Account'] = smc_session()['user_accounts']['cash_account_id'];
            $exchange_arr['Check_Amount'] = 0;
            $exchange_arr['Check_Account'] = '';
            $exchange_arr['Return_Invoice_Total'] = abs($ret_sub_total);
            $exchange_arr['Invoice_Net_Total'] = abs($ret_net_total);
            $exchange_arr['Invoice_VAT'] = abs($ret_vat_total);
            $exchange_arr['vat1_total'] = abs($ret_vat1_total);
            $exchange_arr['vat2_total'] = abs($ret_vat2_total);
            //            $exchange_arr['Discount_Amount'] = abs($return_discount);
            $exchange_arr['discount_amount'] = abs($return_discount);
            $exchange_arr['discount_percent'] = $exchange_arr['Invoice_Discount'];
            $exchange_arr['Return_Invoice_Note'] = $exchange_arr['Invoice_Description'];
            $exchange_arr['Person_ID'] = $exchange_arr['Customer_ID'];
            $exchange_arr['Account_Code'] = smc_session()['user_accounts']['sales_account_id'];
            $exchange_arr['job_id'] = 0;
            $exchange_arr['Old_Depot_ID'] = $row_ex['Depot_ID'];
            $exchange_arr['Products'] = $ret_arr;
            $customer_account = self::getCustomerAccount($exchange_arr['Customer_ID']);
            $exchange_arr['Person_Account'] = $customer_account['Account_ID'];
            //            echo"<pre>"
            $return->setData($exchange_arr)->editReturnNoInvoice();
        }
        if (empty($inv_arr)) {
            $invoice = new Invoice;
            $invoice->stop_transaction_start_end = true;
            $invoice->deleteSalesInvoice([$inv_id]);
        } else {
            if ($delete_ex_flag)
                $this->db->prepare_Stmt('update tbl_invoices set exchange_id = null where Invoice_ID_Auto=?', [&$inv_id]);
            //edit invoice
            $exchange_arr['Invoice_ID_Auto'] = $inv_id;
            $exchange_arr['products'] = $inv_arr;
            $this->stop_transaction_start_end = true;
            $exchange_arr['cash_amount'] = $paid_total > 0 ? abs($paid_total) : 0;
            $exchange_arr['Paid_Amount'] = $paid_total > 0 ? abs($paid_total) : 0;
            $exchange_arr['Invoice_Sub_Total'] = $inv_sub_total;
            $exchange_arr['Invoice_Net_Total'] = $inv_net_total;
            $exchange_arr['Invoice_VAT'] = $inv_vat_total;
            $exchange_arr['vat1_total'] = abs($inv_vat1_total);
            $exchange_arr['vat2_total'] = abs($inv_vat2_total);
            $exchange_arr['Discount_Amount'] = abs($invoice_discount);
            //            echo"<pre>";die(print_r($exchange_arr));
            $this->setdata($exchange_arr)->editInvoice();
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
            /* if (!$delete_ex_flag && smc_session()['default_setting']['sumatra_print'] == 1) {
              $data_arr = $this->get_exchange_by_id($exchange_arr['ex_id']);
              $template_row = Forms::build_print_template('pos_exchange', $data_arr['main'], array('inv_detail' => $data_arr['inv_detail'], 'ret_detail' => $data_arr['ret_detail']));
              $print_w_h = Forms::get_print_width_height('pos');
              $filename = Forms::html2pdf($template_row['html'], $print_w_h);
              Forms::real_print(null, $filename, ['repeat' => $template_row['copies']]);
              } */
            return $delete_ex_flag ? ((empty($inv_id) && !empty($ret_id)) ? [$ret_id, 'return'] : [$inv_id, 'invoice'] ) : [$exchange_arr['ex_id'], 'exchange'];
        } else {
            $this->db->query('ROLLBACK');
            return $error;
        }
    }

    public function update_inv_postpone_status($id, $status) {
        $mydate = date("Y-m-d H:i:s");
        $logged_id = Session::getUserID();
        $is_main_transfer = isset($this->info['is_main_transfer']) ? $this->info['is_main_transfer'] : 0;
        $is_postponed_change = isset($this->info['is_postponed_change']) ? $this->info['is_postponed_change'] : 1;
        $data = [&$status, &$mydate, &$logged_id, &$is_main_transfer, &$this->info['postponed_note'], &$is_postponed_change, &$id];
        $this->db->query('update tbl_invoices set posponted_type = ?,date_time=?,Logged_ID = ?,
            is_main_transfer=?,postponed_note =?,is_postponed_change= ? 
            where Invoice_ID_Auto = ?', $data);
        $error = $this->db->error();
        return $error;
    }

    public static function check_reservation_overlap($product_id, $date_from, $date_to, $detail_id = null) {
        $db = DBConnectorFactory::loadDriver();
        $cond = ' ';
        if (!empty($detail_id)) {
            $cond .= ' and Entery_ID <> "' . $detail_id . '" ';
        }
        $query = $db->query('select * from tbl_invoice_products_details
            where "' . $date_to . '" > reserve_from and "' . $date_from . '" < reserve_to 
                and Product_ID = "' . $product_id . '" ' . $cond);
        $count = $db->rowsno($query);
        if ($count > 0)
            return false;
        return true;
    }

    public function get_totals_all_invoice_type($current_date = null) {
        $condition = '';
        $current_date = !is_null($current_date) ? $current_date : date('Y-m-d');
        if (!empty($this->info['branch_id']))
            $condition .= ' and branch_id = "' . $this->info['branch_id'] . '" ';
        $data = array('total_amount_tables' => ['amount' => 0, 'number' => 0], 'total_amount_delivery' => ['amount' => 0, 'number' => 0],
            'total_amount_takeaway' => ['amount' => 0, 'number' => 0]);
        $start_date = $current_date . ' ' . smc_session()['default_setting']['default_start_time'];
        $end_date = date('Y-m-d H:i:s', strtotime($start_date . ' +1 day -1 second'));
        $condition .= ' and date_created between "' . $start_date . '" and "' . $end_date . '" ';
        $invoice_query = $this->db->query('select * from tbl_invoices 
                                            where  is_committed=0 ' . $condition);
        while ($row = $this->db->assoc($invoice_query)) {
            $total_invoice_with_rate = ($row['Invoice_Shipping'] + $row['Invoice_Net_Total']) * $row['current_rate'];
            if ($row['table_id'] != 0) {
                $data['total_amount_tables']['amount'] += $total_invoice_with_rate;
                $data['total_amount_tables']['number'] += 1;
            }
            if ($row['Is_Delivery'] == 1) {
                $data['total_amount_delivery']['amount'] += $total_invoice_with_rate;
                $data['total_amount_delivery']['number'] += 1;
            }
            if ($row['Inv_Type'] == 2 && $row['table_id'] == 0) {
                $data['total_amount_takeaway']['amount'] += $total_invoice_with_rate;
                $data['total_amount_takeaway']['number'] += 1;
            }
        }
        return $data;
    }

    public function get_user_cashes() {
        $jv = new JV;
        $data = array();
        $branch_data = $this->info;
        $users = User::get_users_with_acc();
        $is_actual = 0;
        foreach ($users as $user) {
            $cash_amount = $jv->setData($branch_data)->getDailyCashPOSQueries($user['User_ID'], $user['cash_account_id'], $is_actual);
            $data[] = array('user' => $user['User_Name'], 'cash_amount' => empty($cash_amount) ? 0 : $cash_amount);
        }
        return $data;
    }

    public function get_total_sales() {
        $user_id = Session::getUserID();
        $condition = '';
        if (!empty($this->info['branch_id'])){
            $condition .= ' and branch_id = "' . $this->info['branch_id'] . '"';
         }else{
            if($this->permissions->hasPermission('Branches')){
                $condition .=  '';

            }else{
                $condition .= ' and branch_id ="' . (smc_session()['user_accounts']['branch_id']) . '"'  ;

            }
         }
        if (!$this->permissions->hasPermission('view_all_pos_invoices'))
            $condition .= ' and created_logged_id = "' . $user_id . '" ';
        $last_close = Invoicepos::get_open_shift_time($user_id);
        $query = $this->db->query('SELECT SUM((Invoice_Net_Total+Invoice_Shipping)*current_rate) AS Amount
                                    FROM tbl_invoices 
                                    WHERE date_time >= "' . $last_close . '"
                                        and is_actual = "' . $this->info['is_actual'] . '"
                                            and is_committed=1
                                        ' . $condition . ' ');



 
        $row = $this->db->assoc($query);
        $balance = $row['Amount'];
        $symbol = smc_session()['local_currency_symbol'];
        $final_balance = '('.CommonLanguage::getMessage('total_sales').': ' . CommonFunctions::public_round_number($balance) . ' ' . $symbol . ' )';
        return $final_balance;
    }

    public function change_inv_rec_date($inv_id, $status) {
        $date = $status == 0 ? NULL : date('Y-m-d H:i:s');
        $data = [$date, $inv_id];
        $this->db->prepare_Stmt('update tbl_invoices set received_date = ? where Invoice_ID_Auto=?', $data);
        $error = $this->db->error();
        return $error;
    }

    public function change_inv_rec_note($inv_id, $note) {
        $this->db->prepare_Stmt('update tbl_invoices set received_note = ? 
            where Invoice_ID_Auto=?', [$note, $inv_id]);
        $error = $this->db->error();
        return $error;
    }

    public static function get_last_close_end_day($branch_id) {
        $db = DBConnectorFactory::loadDriver();
        $close_time = '2019-01-01';
        $cond = '';
        if (!empty($branch_id))
            $cond .= '   and if(ifnull(app_branch_id,0) !=0,app_branch_id,ifnull(branch_id,0)) = "' . $branch_id . '" ';
        $query = $db->query('select close_time from tbl_end_of_shift where type=1 
          ' . $cond . '  order by close_time desc limit 1');
        $row = $db->assoc($query);
        if (!empty($row) && !empty($row['close_time']))
            $close_time = $row['close_time'];
        return $close_time;
    }
    public function OpenCashDrawer() {
        $cash_drawer_port = smc_session()['default_setting']['cash_drawer_port'];
        if(!empty($cash_drawer_port))
            exec("echo Ctrl+G > $cash_drawer_port");
        $error = $this->db->error();
        return $error;
    }


}
