<?php

class Product {

    protected $info = array();
    protected $AllAccounts = array();
    private $db;
    private $perm;
    private $year_id;
    private $year_id_actual;
    public $stop_transaction_start_end = false;

    public function __construct() {
        $this->db = DBConnectorFactory::loadDriver();
        $this->perm = new Permissions(Session::getUserID());
        $this->year_id = Session::getCurrentYearID();
        $this->year_id_actual = Session::getCurrentYearIDActual();
    }

    public function setData($data) {
        $this->info = $data;

        return $this;
    }

    //    public function get
    public function halfYear($start, $end, $year) {
        $sum = 0;
        for ($i = $start; $i < $end; $i++) {
            $val = self::viewSoldQuantity(null, $year, $i);
            $sum += $val;
            $val = 0;
        }
        return $sum;
    }

    public function selectProducts() {
        $data = array();
        $query = $this->db->query('SELECT 
                                        Product_ID,
                                        Product_Name,
                                        Cat_Name
                                    FROM 
                                        datasource_productlist
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        return $data;
    }

    public function addProduct() {
        //        echo"<pre>"
        $logged_id = smc_session()['user_logged_id'];
        $current_date_time = date("Y-m-d H:i:s");
        $this->info['additional_barcodes'] = !empty($this->info['additional_barcodes']) ? trim(preg_replace('/\s+/', ',', $this->info['additional_barcodes'])) : '';
        $sync_query = '';
        $scales_arr = array();
        if (smc_session()['activate_scale'] == 1) {
            $scales_query = $this->db->query('select * from tbl_scale');
            while ($row = $this->db->assoc($scales_query))
                $scales_arr[] = $row;
        }
        if (smc_session()['plu_as_code'] == 1) {
            $plu = !empty($this->info['Bar_Code']) ? ($this->info['Bar_Code'] != '' ? $this->info['Bar_Code'] : $this->info['Product_Code']) : $this->info['Product_Code'];
        } else {
            $plu_query = $this->db->query('select max(Product_PLU) as plu from tbl_stock_products');
            $plu_assoc = $this->db->assoc($plu_query);
            $plu = count($plu_assoc) > 0 ? $plu_assoc['plu'] + 1 : 1;
        }
        if (!$this->stop_transaction_start_end)
            $this->db->query('START TRANSACTION');
        $x = (!empty($this->info['VAT']) ? 1 : 0);
        $to_scale = (!empty($this->info['move_scale']) ? 1 : 0);
        $is_tax = (!empty($this->info['is_card']) ? 1 : 0);
        $is_expiry = (!empty($this->info['is_expiry']) ? 1 : 0);
        $force_change_price = (!empty($this->info['force_change_price']) ? 1 : 0);
        $duration_reservation = (!empty($this->info['duration_reservation']) ? 1 : 0);
        $is_lot = (!empty($this->info['is_lot']) ? 1 : 0);
        $is_serial = (!empty($this->info['is_serial']) ? 1 : 0);
        $is_service = (!empty($this->info['is_service']) ? 1 : 0);
        $is_rate = (!empty($this->info['is_rate']) ? 1 : 0);
        $is_rate_type_one = (!empty($this->info['is_rate_type_one']) ? 1 : 0);
        $is_rate_type_two = (!empty($this->info['is_rate_type_two']) ? 1 : 0);
        $effect_qty_link_product = (!empty($this->info['effect_qty_link_product']) ? 1 : 0);
        $is_ticket = (!empty($this->info['is_ticket']) ? 1 : 0);
        $plu_type = (!empty($this->info['plu_type']) ? 'P' : 'N');
        $printers = empty($this->info['printer_arr']) ? '' : $this->info['printer_arr'];

        if(!is_numeric($this->info['n_width'])){
            $this->info['n_width'] = 0;
        }
        if(!is_numeric($this->info['n_height'])){
            $this->info['n_height'] = 0;
        }
    
        
    
        $this->info['Product_Arabic_Name'] = !empty($this->info['Product_Arabic_Name']) ? $this->info['Product_Arabic_Name'] : '';
        $this->info['current_branch_id'] = !empty($this->info['current_branch_id']) ? $this->info['current_branch_id'] : smc_session()['user_accounts']['branch_id'];
        $this->info['Product_Reorder_Point'] = is_numeric($this->info['Product_Reorder_Point']) ? $this->info['Product_Reorder_Point'] : NULL;
        $this->info['vat_percent'] = !empty($this->info['vat_percent']) ? $this->info['vat_percent'] : '';
        $this->info['vat2_percent'] = !empty($this->info['vat2_percent']) ? $this->info['vat2_percent'] : 0;
        $this->info['product_description'] = !empty($this->info['product_description']) ? $this->info['product_description'] : '';
        $this->info['product_color'] = !empty($this->info['product_color']) ? $this->info['product_color'] : '';
        $this->info['product_type'] = !empty($this->info['product_type']) ? $this->info['product_type'] : 0;
        $this->info['product_order'] = !empty($this->info['product_order']) ? $this->info['product_order'] : '';
        $this->info['Product_Limit_Discount'] = !empty($this->info['Product_Limit_Discount']) ? $this->info['Product_Limit_Discount'] : '';
        $this->info['group_account_id'] = !empty($this->info['group_account_id']) ? $this->info['group_account_id'] : '';
        $this->info['brand_id'] = !empty($this->info['brand_id']) ? $this->info['brand_id'] : '';
        $this->info['pur_cat_id'] = !empty($this->info['pur_cat_id']) ? $this->info['pur_cat_id'] : NULL;
        $this->info['section_id'] = !empty($this->info['section_id']) ? $this->info['section_id'] : '';
        $this->info['link_note'] = !empty($this->info['link_note']) ? $this->info['link_note'] : '';
        $this->info['machine_type_id'] = !empty($this->info['machine_type_id']) ? $this->info['machine_type_id'] : 0;
        $this->info['default_view_uom_id'] = !empty($this->info['default_view_uom_id']) ? $this->info['default_view_uom_id'] : $this->info['UOM_ID'];
        $this->info['default_view_rate'] = !empty($this->info['default_view_rate']) ? $this->info['default_view_rate'] : 1;
        $this->info['family_id'] = !empty($this->info['family_id']) ? $this->info['family_id'] : NULL;
        $this->info['default_sales_uom'] = !empty($this->info['default_sales_uom']) ? $this->info['default_sales_uom'] : 0;
        $this->info['default_purchase_uom'] = !empty($this->info['default_purchase_uom']) ? $this->info['default_purchase_uom'] : 0;
        $this->info['print_uom_id'] = !empty($this->info['print_uom_id']) ? $this->info['print_uom_id'] : 0;
        $this->info['product_second_code'] = !empty($this->info['product_second_code']) ? $this->info['product_second_code'] : NULL;
        $this->info['recipe_qty'] = !empty($this->info['recipe_qty']) ? $this->info['recipe_qty'] : 1;
        $this->info['product_param1'] = !empty($this->info['product_param1']) ? $this->info['product_param1'] : '';
        $this->info['product_param2'] = !empty($this->info['product_param2']) ? $this->info['product_param2'] : '';
        $this->info['product_param3'] = !empty($this->info['product_param3']) ? $this->info['product_param3'] : '';
        $this->info['product_param4'] = !empty($this->info['product_param4']) ? $this->info['product_param4'] : '';
        $arr = [&$this->info['Product_Code'],
            &$this->info['Product_Name'],
            &$this->info['Product_Arabic_Name'],
            &$this->info['Category_ID'],
            &$this->info['Product_Reorder_Point'],
            &$x,
            &$this->info['vat_percent'],
            &$this->info['vat2_percent'],
            &$plu_type,
            &$plu,
            &$to_scale,
            &$this->info['UOM_ID'],
            &$is_tax,
            &$this->info['product_description'],
            &$this->info['product_color'],
            &$this->info['product_order'],
            &$printers,
            &$this->info['product_type'],
            &$this->info['Product_Limit_Discount'],
            &$this->info['group_account_id'],
            &$this->info['brand_id'],
            $this->info['pur_cat_id'],
            &$this->info['link_note'],
            &$current_date_time,
            &$logged_id,
            &$current_date_time,
            &$logged_id, &$this->info['section_id'], &$this->info['machine_type_id'],
            &$is_expiry, &$force_change_price,
            &$duration_reservation, &$this->info['default_view_uom_id'], &$this->info['default_view_rate'],
            &$is_lot, &$is_serial, &$this->info['main_supplier_id'],
            &$this->info['family_id'], &$this->info['default_sales_uom'],
            &$this->info['default_purchase_uom'], &$is_service, &$is_ticket, &$this->info['product_second_code'],
            &$this->info['recipe_qty'], &$this->info['product_param1'], &$this->info['product_param2'],
            &$this->info['product_param3'], &$this->info['product_param4'], &$this->info['print_uom_id'],&$is_rate,&$this->info['current_branch_id']
            ,&$is_rate_type_one
            ,&$is_rate_type_two
            ,&$this->info['n_width']
            ,&$this->info['n_height']
            ,&$effect_qty_link_product
            ,&$this->info['hide_pos']
            ,&$this->info['positive_points']
            ,&$this->info['negative_points']
            
        ];  
        $this->db->prepare_Stmt("INSERT INTO tbl_stock_products
                                            (
                                                Product_Code,
                                                Product_Name,
                                                Product_Arabic_Name,
                                                Category_ID,
                                                Product_Reorder_Point,
                                                Product_VAT,
                                                vat_percent,vat2_percent,
                                                PLU_Type,
                                                Product_PLU,
                                                on_scale,
                                                UOM_ID,
                                                is_tax,
                                                product_description,
                                                product_color,
                                                product_order,
                                                printer_id,
                                                product_type,
                                                Product_Limit_Discount,
                                                group_account_id,
                                                brand_id,pur_cat_id,
                                                link_note,
                                                date_created,
                                                created_logged_id,
                                                date_time,
                                                Logged_ID,
                                                section_id,
                                                machine_type_id,is_expiry,force_change_price,duration_reservation,
                                                default_view_uom_id,default_view_rate,is_lot,is_serial,main_supplier_id,
                                                family_id,default_sales_uom,default_purchase_uom,is_service,is_ticket,
                                                product_second_code,recipe_qty,product_param1,product_param2,product_param3,product_param4,print_uom_id,is_rate,multi_branch_id
                                                ,is_rate_type_one
                                                ,is_rate_type_two
                                                ,n_width 
                                                ,n_height
                                                ,effect_qty_link_product
                                                ,hide_pos1
                                                ,positive_points
                                                ,negative_points
                                            )
                                                VALUES
                                            (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", $arr);


        $pid = $this->db->id();
        $arr_prod = ['type' => 'prod', 'main_id' => $pid, 'action' => 0, 'date_time' => $current_date_time,
            'user_id' => $logged_id];
        CommonFunctions::add_user_log($arr_prod);

        if (!empty($this->info['criteria'])) {
            $criterias = json_decode($this->info['criteria'], true);
            if (smc_session()['default_setting']['is_tag_active'] == 1 && !empty($criterias)) {
                foreach ($criterias as $criteria) {
                    $max_count = $criteria['criteria_type'] == 1 ? $criteria['criteria_max_count'] : 1;
                    $criteria_data = [&$criteria['criteria_name'], &$criteria['criteria_type'], &$max_count, &$pid];
                    $this->db->prepare_Stmt("INSERT INTO tbl_product_criteria (criteria_name,criteria_type,criteria_max_count,is_required,Product_ID) 
                                                            VALUES(?,?,?,0,?)
                    ", $criteria_data);
                    $criteria_id = $this->db->id();
                    //                    $criteria_details = explode('#####', preg_replace('/(\r?\n){1}/', '#####', $criteria['criteria_details']));
                    //                    $criteria_details = ;
                    foreach ($criteria['criteria_details'] as $details) {
                        $this->db->prepare_Stmt("INSERT INTO  tbl_product_criteria_detail (criteria_detail_name,criteria_detail_price,criteria_id) 
                                                            VALUES(?,?,?)
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$criteria_id]);
                    }
                }
            }
        }
        $today = Date::getToday();
        $class_price_arr = array();
        if (!empty($this->info['price_arr'])) {
            $classes = json_decode($this->info['price_arr'], true);
            foreach ($classes as $class) {
                $data = [&$class['class_id'], &$pid, &$this->info['UOM_ID'], &$class['price'], &$class['currency_id'], &$today];
                $class_price_arr[$class['class_id']] = $class['price'];
                $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,Pricing_Date) '
                        . '                 VALUES(?,?,?,?,?,?)', $data);

                if (smc_session()['default_setting']['activate_price_log'] == 1) {
                    $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes_log (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,date_time,Logged_ID) '
                            . '                 VALUES(?,?,?,?,?,?,?)', [
                        &$class['class_id'], &$pid, &$this->info['UOM_ID'], &$class['price'], &$class['currency_id'], &$current_date_time, &$logged_id]);
                }
            }
        }
        $barcode = !empty($this->info['Bar_Code']) ? ($this->info['Bar_Code'] != '' ? $this->info['Bar_Code'] : $this->info['Product_Code']) : $this->info['Product_Code'];

        $data_conv = [&$this->info['UOM_ID'], &$this->info['UOM_ID'], &$pid, &$barcode, &$this->info['additional_barcodes']];
        $this->db->prepare_Stmt('INSERT INTO tbl_uom_conversions 
                                                    (uom_from,
                                                    conversion_amount,
                                                    uom_to,
                                                    Product_ID,
                                                    is_default,
                                                    Bar_Code,
                                                    additional_barcodes
                                                    )
                                                    VALUES(?,1,?,?,1,?,?)
                                                    ', $data_conv);
        if (isset($this->info['current_added_id'])) {
            $this->db->prepare_Stmt('INSERT INTO tbl_stock_products_parts 
                                                    (part_product_id,
                                                    Product_ID,
                                                    part_note
                                                    )
                                                    VALUES(?,?,?)
                                                    ', [&$pid, &$this->info['current_added_id'], &$this->info['part_note']]);
        }
        if (!empty($this->info['con'])) {
            $uom_conversions = json_decode($this->info['con'], true);
            foreach ($uom_conversions as $uoms) {
                if ($uoms['conversion_amount'] != '' && $uoms['uom_from'] != '') {
                    $uoms['additional_barcodes'] = trim(preg_replace('/\s+/', ',', $uoms['additional_barcodes']));
                    $uoms['code'] = $uoms['code'] == '' ? NULL : $uoms['code'];
                    $data1 = [&$uoms['uom_from'], &$uoms['conversion_amount'], &$this->info['UOM_ID'], &$pid, &$uoms['code'], &$uoms['additional_barcodes']];

                    $this->db->prepare_Stmt('INSERT INTO tbl_uom_conversions (uom_from,conversion_amount,uom_to,Product_ID,is_default,Bar_Code,additional_barcodes) '
                            . '                 VALUES(?,?,?,?,0,?,?)', $data1);
                    foreach ($uoms['uom_prices'] as $uom_price) {

                        $data = [&$uom_price['class_id'], &$pid, &$uoms['uom_from'], &$uom_price['price'], &$uom_price['currency_id'], &$today];
                        $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,Pricing_Date) '
                                . '                 VALUES(?,?,?,?,?,?)', $data);
                    }
                }
            }
        }
        if (!empty($this->info['in_item'])) {
            $in_products = json_decode($this->info['in_item'], true);
            foreach ($in_products as $in) {
                $in_qty = Product::getConvertedQuantity($in['sub_uom'], $in['sub_qty'], $in['sub_item']);
                $in_data = [&$pid, &$in['sub_item'], &$in_qty, &$in['sub_qty'], &$in['sub_uom']];
                $this->db->prepare_Stmt('insert into tbl_products_link (main_product_id,sub_product_id,quantity,operation,current_quantity,UOM_ID)
                                        values(?,?,?,"+",?,?)', $in_data);
            }
        }
        if (!empty($this->info['out_item'])) {
            $out_products = json_decode($this->info['out_item'], true);
            foreach ($out_products as $out) {
                $out_qty = Product::getConvertedQuantity($out['sub_uom'], $out['sub_qty'], $out['sub_item']);
                $in_data = [&$pid, &$out['sub_item'], &$out_qty, &$out['sub_qty'], &$out['sub_uom']];
                $this->db->prepare_Stmt('insert into tbl_products_link (main_product_id,sub_product_id,quantity,operation,current_quantity,UOM_ID)
                                        values(?,?,?,"-",?,?)', $in_data);
            }
        }
        if (!empty($this->info['product_shelf'])) {
            $product_shelf = json_decode($this->info['product_shelf'], true);
            foreach ($product_shelf as $prd_shlf) {
                if (!empty($prd_shlf['shelf_depot_id'])) {
                    $shelf_depot_id = explode(',', $prd_shlf['shelf_depot_id']);
                    foreach ($shelf_depot_id as $depot_shlf) {
                        $data = [
                            &$pid,
                            &$depot_shlf,
                            &$prd_shlf['depot_id']
                        ];
                        $this->db->prepare_Stmt('insert into tbl_product_shelf (`product_id`, `shelf_depot_id`, `depot_id`) VALUES (?,?,?)', $data);
                    }
                }
            }
        }
        if (!empty($this->info['add_ons'])) {
            $add_ons = json_decode($this->info['add_ons'], true);
            if (smc_session()['default_setting']['is_add_ons_active'] == 1 && !empty($add_ons)) {
                foreach ($add_ons as $details) {
                    $this->db->prepare_Stmt('INSERT INTO tbl_product_add_ons
            (product_add_ons_quantity,add_ons_id,product_id) '
                            . '                 VALUES(?,?,?)', [&$details['product_add_ons_quantity'], &$details['add_ons_id'], &$pid]);
                    $product_add_ons_id = $this->db->id();
                    $product_add_ons = 'INSERT INTO tbl_meal_add_ons
            (meal_add_ons_quantity,add_ons_id,meal_id,meal_add_ons_id_offline,branch_id) '
                            . '                 VALUES(?,
                                    (SELECT  add_ons_id FROM tbl_add_ons WHERE add_ons_id_offline = ? and branch_id = "' . SMARTDINER_BRANCH_ID . '"),
                                    (SELECT  meal_id FROM tbl_meal WHERE meal_id_offline = "' . $pid . '" and branch_id = "' . SMARTDINER_BRANCH_ID . '"),"' . $product_add_ons_id . '" ,"' . SMARTDINER_BRANCH_ID . '")';
                    $sync_query .= $this->db->is_logged_query($product_add_ons, [$details['product_add_ons_quantity'],
                        $details['add_ons_id']]);
                }
            }
        }
        if (!empty($this->info['prop_arr']) && !empty($this->info['machine_type_id']) && $this->info['machine_type_id'] == 1) {
            $prop_arr = json_decode($this->info['prop_arr'], true);
            foreach ($prop_arr as $prop) {
                $this->db->prepare_Stmt('INSERT INTO `tbl_stock_product_properties`( `property_name`,
                `Product_ID`) VALUES (?,?)', [&$prop['property_name'], &$pid]);
            }
        }

        if (!empty($this->info['optionals'])) {
            $optionals = json_decode($this->info['optionals'], true);
            foreach ($optionals as $option) {
                $data = [$pid, $option['quantity'], $option['is_required']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_options`( `product_id`, `quantity`,
                   `is_required`, `operation`) values(?,?,?,"-")', $data);
                $option_id = $this->db->id();
                if (!empty($option['details'])) {
                    foreach ($option['details'] as $det) {
                        $det_arr = [$option_id, $det['product_id'], $det['uom_id']];
                        $this->db->prepare_Stmt('INSERT INTO `tbl_product_option_details`( `option_id`,
                        `sub_product_id`, `UOM_ID`) values(?,?,?)', $det_arr);
                    }
                }
            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            if (!$this->stop_transaction_start_end)
                $this->db->query('COMMIT');
            $uploaddir = upload_path . 'products_photos/';
            $this->SaveUploadedPhoto(!empty($this->info['current_image_file']) ? $this->info['current_image_file'] : "image_file", $uploaddir . $pid . '.jpg', !empty($this->info['current_image_file']) ? false : true);
            if ($to_scale == 1 && smc_session()['activate_scale'] == 1) {
                foreach ($scales_arr as $scale_row) {
                    $class_id = $scale_row['class_id'];
                    $prod_price = (empty($class_id) ? $this->info['price'] : $class_price_arr[$class_id]);
                    $scale_prod_arr = array(array('Product_PLU' => $plu, 'Product_Name' => $this->info['Product_Name'],
                            'Product_Description' => $this->info['Product_Arabic_Name'], 'Product_Code' => $this->info['Bar_Code']/* printed on barcode */
                            , 'PLU_Type' => $plu_type, 'Product_Price' => $prod_price));
                    $scale = scale::scale_obj($scale_row);
                    $scale->register_products($scale_prod_arr);
                }
            }
            if (smc_session()['default_setting']['is_sync_active'] == 1) {
                $class_id = !empty(smc_session()['default_setting']['smart_diner_app_class_id']) ? smc_session()['default_setting']['smart_diner_app_class_id'] : smc_session()['default_setting']['pricing_class_id'];
                $online_product_price = self::get_product_price($pid, $class_id, $this->info['UOM_ID']);
                $product_data = 'INSERT INTO tbl_meal
                                                    (meal_name,
                                                    meal_price,
                                                    meal_description,
                                                    category_id,
                                                    meal_image,
                                                    meal_id_offline,
                                                    branch_id)
                                                        VALUES
                                                    (?,
                                                    ?,
                                                    ?,
                                                    (SELECT  category_id FROM tbl_category WHERE category_id_offline = ? and branch_id = ?),
                                                    ?,
                                                    ?,
                                                    ?)';
                $this->db->is_logged_data($product_data, [$this->info['Product_Name'],
                    $online_product_price,
                    $this->info['product_description'],
                    $this->info['Category_ID'],
                    SMARTDINER_BRANCH_ID,
                    '',
                    $pid,
                    SMARTDINER_BRANCH_ID]);
                $criteria_query = $this->db->query('select * from tbl_product_criteria where Product_ID ="' . $pid . '"');
                while ($row = $this->db->assoc($criteria_query)) {
                    $criteria_data = 'INSERT INTO tbl_meal_criteria (
                                                    criteria_name,
                                                    criteria_type,
                                                    criteria_max_count,
                                                    is_required,
                                                    meal_id,
                                                    criteria_id_offline,
                                                    branch_id) 
                                            VALUES(?,?,?,?,
                                            (select meal_id from tbl_meal where meal_id_offline = ? and branch_id = ?),
                                            ?,?)';
                    $this->db->is_logged_data($criteria_data, [$row['criteria_name'], $row['criteria_type'],
                        $row['criteria_max_count'], $row['is_required'],
                        $pid, SMARTDINER_BRANCH_ID, $row['criteria_id'], SMARTDINER_BRANCH_ID]);
                }
                $criteria_details_query = $this->db->query('select details.* from tbl_product_criteria_detail details inner join tbl_product_criteria criteria using(criteria_id) where criteria.Product_ID ="' . $pid . '" ');
                while ($row2 = $this->db->assoc($criteria_details_query)) {
                    $criteria_detail_data = 'INSERT INTO tbl_meal_criteria_detail (
                                                            criteria_detail_name,
                                                            criteria_detail_price,
                                                            criteria_id,
                                                            criteria_detail_id_offline,
                                                            branch_id) 
                                                    VALUES(?,?,(select criteria_id from tbl_meal_criteria where criteria_id_offline=?  and branch_id =?),?,?)';
                    $this->db->is_logged_data($criteria_detail_data, [$row2['criteria_detail_name'], NULL, $row2['criteria_id'], SMARTDINER_BRANCH_ID, $row2['criteria_detail_id'], SMARTDINER_BRANCH_ID]);
                }
                $this->db->is_logged_file($sync_query);
            }
        } else {
            if (!$this->stop_transaction_start_end)
                $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function submitGeneralCriteria() {
        $this->db->query('START TRANSACTION');
        $criterias = $this->info['criteria'];
        $current_criteria_id = $this->info['criteria_id'];
        if ($current_criteria_id == 0) {
            foreach ($criterias as $criteria) {
                $max_count = $criteria['criteria_type'] == 1 ? $criteria['criteria_max_count'] : 1;
                $criteria_data = [&$criteria['criteria_name'], &$criteria['criteria_type'],
                    &$max_count, &$criteria['category_id']];
                $this->db->prepare_Stmt("INSERT INTO tbl_product_criteria (criteria_name,criteria_type,criteria_max_count,is_required,category_id) 
                                                            VALUES(?,?,?,0,?)
                    ", $criteria_data);
                $criteria_id = $this->db->id();
                foreach ($criteria['criteria_details'] as $details) {
                    $this->db->prepare_Stmt("INSERT INTO  tbl_product_criteria_detail (criteria_detail_name,criteria_detail_price,criteria_id) 
                                                            VALUES(?,?,?)
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$criteria_id]);
                }
            }
        } else {
            $criteria = $this->info['criteria'][0];
            $max_count = $criteria['criteria_type'] == 1 ? $criteria['criteria_max_count'] : 1;
            $this->db->prepare_Stmt("update tbl_product_criteria set criteria_name = ?,criteria_type = ?,criteria_max_count =?,is_required =0,category_id = ?  where criteria_id = ?
                    ", [&$criteria['criteria_name'], &$criteria['criteria_type'], &$max_count, &$criteria['category_id'],
                &$current_criteria_id]);

            $current_details_ids = $this->info['criteria_detail_ids'];
            $criteria_detail_cond = !empty($current_details_ids) ? ' and criteria_detail_id not in(' . implode(',', $current_details_ids) . ') ' : '';

            $this->db->prepare_Stmt('delete from tbl_product_criteria_detail 
                            where  criteria_id = ? ' . $criteria_detail_cond, [&$current_criteria_id]);

            foreach ($criteria['criteria_details'] as $details) {
                $criteria_detail_id = $details['criteria_detail_id'];
                if ($criteria_detail_id == 0) {
                    $this->db->prepare_Stmt("INSERT INTO  tbl_product_criteria_detail (criteria_detail_name,criteria_detail_price,criteria_id) 
                                                            VALUES(?,?,?)
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$current_criteria_id]);
                } else {
                    $this->db->prepare_Stmt("update  tbl_product_criteria_detail set criteria_detail_name = ?,criteria_detail_price =? ,criteria_id =? where criteria_detail_id =?  
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$current_criteria_id, &$criteria_detail_id]);
                }
            }
        }

        $error = $this->db->error();

        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    //    public function addProduct() {
    //        $this->db->query('START TRANSACTION');
    //        $valid = new validate($this->info);
    //        $valid
    //                ->field("Category_ID", "Category ID")->is_numericChar()
    //                ->field("Currency_ID", "Currency ID")->is_numericChar()
    //                ->field("Product_Cost", "Cost")->is_floatChar()
    //                ->field("Product_Price", "Price")->is_floatChar()
    //                ->field("Product_Reorder_Point", "Reorder Point")->is_floatChar();
    //        $error = $valid->evaluate();
    //        if (!empty($error))
    //            return $error;
    //
    //        $x = (array_key_exists('VAT', $this->info) ? 1 : 0);
    //        $arr = [&$this->info['Product_Code'],
    //            &$this->info['Product_Name'],
    //            &$this->info['Category_ID'],
    //            &$this->info['Currency_ID'],
    //            &$this->info['Product_Cost'],
    //            &$this->info['Product_Price'],
    //            &$this->info['Product_Reorder_Point'],
    //            &$x];
    //        $this->db->prepare_Stmt("INSERT INTO tbl_stock_products
    //                                            (
    //                                                Product_Code,
    //                                                Product_Name,
    //                                                Category_ID,
    //                                                Currency_ID,
    //                                                Product_Cost,
    //                                                Product_Price,
    //                                                Product_Reorder_Point,
    //                                                Product_VAT
    //                                            )
    //                                                VALUES
    //                                            (
    //                                            ?,?,?,?,?,?,?,?
    //                                            
    //
    //                                                )", $arr);
    //        $pid = $this->db->id();
    //        $class_query = $this->db->query('SELECT DISTINCT Class_ID,Currency_ID FROM tbl_item_price_by_classes');
    //        $classes = array();
    //        while ($row = $this->db->assoc($class_query)) {
    //            $classes[] = $row;
    //        }
    //        $today = Date::getToday();
    //        foreach ($classes as $class) {
    //            $data = [&$class['Class_ID'], &$pid, &$this->info['Product_Price'], &$class['Currency_ID'], &$today];
    //            $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,Product_Price,Currency_ID,Pricing_Date) '
    //                    . '                 VALUES(?,?,?,?,?)', $data);
    //        }
    //        $error = $this->db->error();
    //        if (empty($error)) {
    //            $this->db->query('COMMIT');
    //            $uploaddir = upload_path . 'products_photos/';
    //                $this->SaveUploadedPhoto("image_file", $uploaddir . $pid . '.jpg');
    //        } else {
    //            $this->db->query('ROLLBACK');
    //        }
    //        return array_unique($error);
    //    }

    public function getProducts() {
        $data = array();

        $query = $this->db->query('SELECT
                                        p.Product_ID,
                                        p.Product_Code,
                                        p.Product_Name,
                                        p.Product_Quantity,
                                        p.Product_VAT,
                                        c.*,
                                        y.*,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                        u.Bar_Code,
                                        u.uom_from AS UOM_ID

                                    FROM
                                        tbl_stock_products p
                                    LEFT JOIN
                                        tbl_product_cat c
                                    ON
                                        c.Cat_ID = p.Category_ID
                                   LEFT JOIN
                                        tbl_common_currency y
                                    ON
                                        y.Currency_ID = p.Currency_ID    
                                    LEFT JOIN 
                                        uom_conversions u
                                    ON 
                                        p.Product_ID = u.Product_ID
                                    WHERE
                                        p.Status_ID = 1
                                    GROUP BY 
                                        u.Bar_Code
                                    ORDER BY    
                                        u.Is_Default DESC
                ');

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

    //    public function getMainProducts() {
    //        $data = array();
    //
    //        $query = $this->db->query('SELECT * FROM product_info');
    //
    //        while ($row = $this->db->assoc($query)) {
    //            $data[] = $row;
    //        }
    //        return $data;
    //    }

    public function getUOMByProduct($id) {
        $data = array();

        $query = $this->db->query('SELECT * FROM uom_conversions WHERE Product_ID = "' . $id . '"');

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

    public function getUOMPricesByProduct($id) {
        $data = array();
        $uoms_from = array();
        $query = $this->db->query('SELECT * FROM uom_conversions WHERE Product_ID = "' . $id . '" and is_default <> 1');

        while ($row = $this->db->assoc($query)) {
            $row['is_used'] = self::checkIfProductUOMUsed($id, $row['uom_from']) ? 1 : 0;
            $row['additional_barcodes'] = trim(str_replace(',', '&#10;', $row['additional_barcodes']));
            $data[$row['uom_from']] = $row;
            $uoms_from[] = $row['uom_from'];
        }
        if (!empty($uoms_from)) {
            $uoms = implode(',', $uoms_from);

            $query_price = $this->db->query('select * from tbl_item_price_by_classes where Product_ID = "' . $id . '" and UOM_ID in (' . $uoms . ')');
            while ($prow = $this->db->assoc($query_price)) {
                $data[$prow['UOM_ID']]['price'][$prow['Class_ID']] = $prow;
            }
        }
        //        echo"<pre>";die(print_r($data));
        return $data;
    }

    public function addCategory() {
        $data = [&$this->info['Cat_Name'], &$this->info['Parent_ID'], &$this->info['hide_pos'],
            &$this->info['order_id'], &$this->info['category_color'], &$this->info['category_description'], &$this->info['category_prefix_barcode'],&$this->info['multi_branch_id']];
        $this->db->prepare_Stmt('INSERT INTO tbl_product_cat (Cat_Name,Parent_ID,hide_pos,order_id,category_color,category_description,category_prefix_barcode,multi_branch_id1) VALUES (?,?,?,?,?,?,?,?)', $data);
        $category_id = $this->db->id();
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
            $uploaddir = upload_path . 'category_photos/';
            $this->SaveUploadedPhoto("new_image_name", $uploaddir . $category_id . '.jpg');
            if (smc_session()['default_setting']['is_sync_active'] == 1) {
                $category_data = 'INSERT INTO tbl_category (category_name,branch_id,category_id_offline) VALUES (?,?,?)';
                $this->db->is_logged_data($category_data, [$this->info['Cat_Name'], SMARTDINER_BRANCH_ID, $category_id]);
                //                if($_FILES['new_image_name']['name'] != ""){
                //                    $image_path = 'uploads/category_photos/'. $category_id . '.jpg';
                //                    $this->db->is_logged_image($image_path,'add');
                //                }
            }
            return $category_id;
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function deletePOSCat($CID) {
        $data = [&$CID];
        $this->db->prepare_Stmt('DELETE FROM tbl_product_cat WHERE Cat_ID = ?', $data);
        $error = $this->db->error();
        if (empty($error)) {
            $exist_img = upload_path . 'category_photos/' . $CID . '.jpg';
            if (file_exists($exist_img))
                unlink($exist_img);
            if (smc_session()['default_setting']['is_sync_active'] == 1) {
                $category_data = 'Delete from tbl_category where branch_id = ?  and category_id_offline = ?';
                $this->db->is_logged_data($category_data, [SMARTDINER_BRANCH_ID, $CID]);
            }
        }
        return $error;
    }

    public function renamePOSCat() {
        $data = [&$this->info['Cat_Name'], &$this->info['hide_pos'],
            &$this->info['order_id'], &$this->info['category_color'], $this->info['Parent_ID'], &$this->info['category_description'], &$this->info['category_prefix_barcode'],&$this->info['multi_branch_id'], &$this->info['CATID']];
        $this->db->prepare_Stmt('UPDATE tbl_product_cat SET Cat_Name = ?,hide_pos=?,order_id=?,
            category_color = ?,Parent_ID = ?,category_description = ?,category_prefix_barcode = ?,multi_branch_id1 = ? WHERE Cat_ID = ? ', $data);
        $error = $this->db->error();
        if (empty($error)) {
            $uploaddir = upload_path . 'category_photos/';
            $this->SaveUploadedPhoto("edited_image_name", $uploaddir . $this->info['CATID'] . '.jpg');
            if (smc_session()['default_setting']['is_sync_active'] == 1) {
                $category_data = 'Update  tbl_category set category_name = ? where branch_id = ?  and category_id_offline = ?';
                $this->db->is_logged_data($category_data, [$this->info['Cat_Name'], SMARTDINER_BRANCH_ID, $this->info['CATID']]);
                //                if($_FILES['edited_image_name']['name'] != ""){
                //                    $image_path = 'uploads/category_photos/'. $this->info['CATID'] . '.jpg';
                //                    $this->db->is_logged_image($image_path,'edit');
                //                }
            }
        }
        return $error;
    }

    public function getCat() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_product_cat');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    //to be edited
    public function getProductsCat($PID = '', $hide = null , $sort_by = 'c.order_id asc') {
        $AllAccounts = [];
        $condition = '';

        if($this->perm->hasPermission('Branches')){
            $condition .= '';
        }else{
            $condition .= ' and (c.multi_branch_id1 in (' . (smc_session()['user_accounts']['branch_id']) . ') OR c.multi_branch_id1 LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR c.multi_branch_id1 LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR c.multi_branch_id1 like "%,' . (smc_session()['user_accounts']['branch_id']) . '")  ' ;
        }

        $query = $this->db->query('SELECT c.*,ifnull(p.Cat_Name,"") as parent_name
            FROM tbl_product_cat c
            left join tbl_product_cat p on p.Cat_ID = c.Parent_ID
            WHERE c.Parent_ID = "' . $PID . '" ' . (empty($hide) ? '' : 'and c.hide_pos <> 1') . ' ' . $condition . '
                order by ' . $sort_by . ' ');
        $index = 0;
        while ($row = $this->db->assoc($query)) {
            $Thumb = file_exists(upload_path . 'category_photos/' . $row['Cat_ID'] . '.jpg');
            $AllAccounts[$index] = array(
                $row['Cat_ID'],
                $row['Cat_Name'],
                (empty($hide) ? $row['hide_pos'] : 0), //for $hide in pos it is override by has children or not [with sub-category, product or not]
                $row['order_id'],
                $row['category_color'],
                $Thumb, $row['Parent_ID'], $row['parent_name'], $row['category_description'], $row['category_prefix_barcode']
            );
            $index++;
        }
        return $AllAccounts;
    }

    //to be edited
    public function getProductCat($CID) {
        $query = $this->db->query('SELECT * FROM tbl_product_cat WHERE Cat_ID = "' . $CID . '"');
        while ($row = $this->db->assoc($query)) {
            $Cat_Name = $row['Cat_Name'];
        }
        return $Cat_Name;
    }

    //to be edited
    public function getProduct($CatID) {
        $condition = '';
        if (smc_session()['default_setting']['show_products_from_all_branches'] == 0) {
            $depot_id = !empty(smc_session()['user_accounts']['depot_id']) ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'];
            $branch_id = CommonBusiness::getBranchByDepot($depot_id);
            $condition = ' and (branch_id is null or concat_ws("", ",", branch_id, ",") LIKE  "%,' . $branch_id . ',%")';
        }
        $query = $this->db->query('SELECT * FROM tbl_stock_products
                            WHERE Category_ID = "' . $CatID . '" AND Status_ID = 1 and hide_pos1 = 0' . $condition);
        $result = $this->db->rowsno($query);
        if ($result == 0)
            return array();
        $index = 0;
        while ($row = $this->db->assoc($query)) {
            $AllAccounts[$index] = array(
                $row['Product_ID'],
                $row['Product_Code'],
                $row['Product_Name'],
                $row['Product_Quantity'],
                $row['Product_Cost'],
                $row['Product_Price'],
                $row['Currency_ID'],
                $row['Product_VAT'],
                $row['force_change_price']
            );
            $index++;
        }
        return $AllAccounts;
    }

    //to be edited
    public function getProductInfo($PID) {
        $data = array();
        $query = $this->db->query('SELECT
                                        p.*,
                                        c.*,
                                        y.*,
                                        uc.Bar_Code,
                                        uc.additional_barcodes,
                                        u.UOM_Name,
                                        ga.group_name,
                                        br.brand_name,
                                        sec.section_name,ss.Supplier_Name as main_supplier_name,
                                        family.family_name,
                                        pc.pur_cat_name
                                    FROM
                                        tbl_stock_products p
                                    LEFT JOIN
                                        tbl_product_cat c
                                    ON
                                        c.Cat_ID = p.Category_ID
                                   LEFT JOIN
                                        tbl_common_currency y
                                    ON
                                        y.Currency_ID = p.Currency_ID
                                    left join
                                        tbl_uom_conversions uc
                                    on 
                                        uc.Product_ID = p.Product_ID
                                    left join
                                            tbl_stock_uom u
                                    on
                                            u.UOM_ID = p.UOM_ID
                                    left join tbl_group_accounts ga on  ga.group_account_id = p.group_account_id
                                    left join tbl_brand_products br on  br.brand_id = p.brand_id
                                    left join tbl_inventory_family family on  family.family_id = p.family_id
                                    left join tbl_product_sections sec on sec.section_id = p.section_id
                                    left join tbl_stock_suppliers ss on ss.Supplier_ID = p.main_supplier_id
                                    left join tbl_purchase_cat pc on p.pur_cat_id = pc.pur_cat_id
                                    WHERE
                                        p.Product_ID = "' . $PID . '"
                                    AND 
                                        p.Status_ID = 1
                                    AND 
                                        uc.is_default = 1

                    ');
        $row = $this->db->assoc($query);
        if (empty($row))
            return ['unable_view_edit_product'];
        $row['is_used'] = self::checkIfProductUOMUsed($PID, $row['UOM_ID']) ? 1 : 0;
        $row['product_branch_name'] = !empty(CommonBusiness::getBranchByBranchId($row['branch_id'])) ? CommonBusiness::getBranchByBranchId($row['branch_id'])['branch_name']:'';
        //        $row['service_used'] = 0;
        //        if ($row['is_service'] == 1) {
        $row['service_used'] = self::checkIfProductUOMUsed($PID) ? 1 : 0;
        //        }
        //        $row['service_used'] = self::checkIfProductUOMUsed($PID, $row['UOM_ID']) ? 1 : 0;
        $row['printers'] = explode(',', $row['printer_id']);
        $row['additional_barcodes'] = trim(str_replace(',', '&#10;', $row['additional_barcodes']));
        $data[] = $row;
        //
        $data['shelfs'] = array();
        $query_shelf = $this->db->prepare_Stmt('select 
                                                       shd.depot_id,
                                                       shd.shelf_name,
                                                       shd.shelf_depot_id,
                                                       dep.Depot_Name
                                                      from tbl_product_shelf psh
                                                inner join 
                                                     tbl_shelfs_depot shd 
                                                on
                                                    psh.shelf_depot_id = shd.shelf_depot_id
                                                inner join 
                                                     tbl_stock_depot_warehouse dep 
                                                on
                                                    dep.Depot_ID = psh.depot_id
                                                where psh.product_id = ? order by psh.product_shelf_id', [&$PID]);
        while ($row_shelf = $this->db->assoc($query_shelf)) {
            if (!isset($data['shelfs'][$row_shelf['depot_id']]))
                $data['shelfs'][$row_shelf['depot_id']] = array('depot_name' => $row_shelf['Depot_Name'], 'shelfs' => array(), 'current_shelfs' => array());
            $data['shelfs'][$row_shelf['depot_id']]['shelfs'][$row_shelf['shelf_depot_id']] = $row_shelf['shelf_name'];
            $data['shelfs'][$row_shelf['depot_id']]['current_shelfs'][] = ['id' => $row_shelf['shelf_depot_id'],
                'text' => $row_shelf['shelf_name']];
        }
        return $data;
    }

    public function getProductLocations($PID) {
        $query = $this->db->query('SELECT * FROM tbl_product_locations WHERE Product_ID = "' . $PID . '"');
    }

    public function getProductsToReorder() {
        $AllAccounts = [];
        $query = $this->db->query('SELECT * 
                                    FROM 
                                        tbl_stock_products 
                                    WHERE 
                                        Status_ID = 1
                                    AND
                                        Product_Reorder_Point >= Product_Quantity');
        while ($row = $this->db->assoc($query)) {
            $AllAccounts[] = $row;
        }
        return $AllAccounts;
    }

    public function getProductLocation($PID) {
        $query = $this->db->query('SELECT * FROM tbl_product_locations WHERE Product_ID = "' . $PID . '"');
        $index = 0;
        while ($row = $this->db->assoc($query)) {
            $this->Product_Location[$index] = array(
                $row['id'],
                $row['Warehouse_ID'],
                $row['Shelf_ID'],
                $row['Product_Quantity']
            );
            $index++;
        }
        return $this->Product_Location;
    }

    public function getWarehouseshasProduct($PID) {
        $query = $this->db->query('SELECT * FROM tbl_stock_warehouses ORDER BY Warehouse_Name ASC');
        $index = 0;
        while ($row = $this->db->assoc($query)) {
            $this->warehouses[$index] = array(
                $row['Warehouse_Code'],
                $row['Warehouse_Name'],
                $row['Warehouse_Address'],
                $row['City_ID'],
                $row['Warehouse_ID']
            );
            $index++;
        }
        return $this->warehouses;
    }

    public function getLastSalesOrder() {
        $Invoice = '';
        $query = $this->db->query('SELECT * FROM tbl_invoices ORDER BY Invoice_ID DESC limit 1');
        while ($row = $this->db->assoc($query)) {
            $Invoice = $row['Invoice_ID'];
        }
        return $Invoice;
    }

    //    public function getAllCurrencies() {
    //        $data = array();
    //        $query = $this->db->query('SELECT * FROM tbl_common_currency');
    //        while ($row = $this->db->assoc($query)) {
    //            $data[] = $row;
    //        }
    //        return $data;
    //    }

    public function updateProduct() {
        $scales_arr = array();
        $current_date_time = date("Y-m-d H:i:s");
        $sync_query = '';
        $this->info['additional_barcodes'] = !empty($this->info['additional_barcodes']) ? trim(preg_replace('/\s+/', ',', $this->info['additional_barcodes'])) : '';
        $this->db->query('START TRANSACTION');
        //        $logged_id = smc_session()['user_logged_id'];
        $scales_query = $this->db->query('select * from tbl_scale');
        while ($row = $this->db->assoc($scales_query))
            $scales_arr[] = $row;
        if (smc_session()['plu_as_code'] == 1) {
            $plu = !empty($this->info['Bar_Code']) ? ($this->info['Bar_Code'] != '' ? $this->info['Bar_Code'] : $this->info['Product_Code']) : $this->info['Product_Code'];
        } else {
            $plu = $this->info['Product_PLU'];
        }

        if(!is_numeric($this->info['n_width'])){
        $this->info['n_width'] = 0;
        }
        if(!is_numeric($this->info['n_height'])){
        $this->info['n_height'] = 0;
        }

        $this->info['move_scale'] = (!empty($this->info['move_scale']) ? 1 : 0);
        $this->info['is_card'] = (!empty($this->info['is_card']) ? 1 : 0);
        //        $this->info['plu_type'] = $this->info['plu_type'];
        $this->info['printer_id'] = !empty($this->info['printer_arr']) ? $this->info['printer_arr'] : ''; //!empty($this->info['printer_id']) ? $this->info['printer_id'] : '';
        $this->info['Product_VAT'] = !empty($this->info['Product_VAT']) ? $this->info['Product_VAT'] : '';
        $this->info['Product_Arabic_Name'] = !empty($this->info['Product_Arabic_Name']) ? $this->info['Product_Arabic_Name'] : '';
        $this->info['Product_Reorder_Point'] = is_numeric($this->info['Product_Reorder_Point']) ? $this->info['Product_Reorder_Point'] : NULL;
        $this->info['vat_percent'] = !empty($this->info['vat_percent']) ? $this->info['vat_percent'] : '';
        $this->info['vat2_percent'] = !empty($this->info['vat2_percent']) ? $this->info['vat2_percent'] : 0;
        $this->info['product_description'] = !empty($this->info['product_description']) ? $this->info['product_description'] : '';
        $this->info['product_color'] = !empty($this->info['product_color']) ? $this->info['product_color'] : '';
        $this->info['product_type'] = !empty($this->info['product_type']) ? $this->info['product_type'] : 0;
        $this->info['product_order'] = !empty($this->info['product_order']) ? $this->info['product_order'] : '';
        $this->info['Product_Limit_Discount'] = !empty($this->info['Product_Limit_Discount']) ? $this->info['Product_Limit_Discount'] : '';
        $this->info['group_account_id'] = !empty($this->info['group_account_id']) ? $this->info['group_account_id'] : '';
        $this->info['brand_id'] = !empty($this->info['brand_id']) ? $this->info['brand_id'] : '';
        $this->info['pur_cat_id'] = !empty($this->info['pur_cat_id']) ? $this->info['pur_cat_id'] : NULL;
        $this->info['link_note'] = !empty($this->info['link_note']) ? $this->info['link_note'] : '';
        $this->info['default_view_uom_id'] = !empty($this->info['default_view_uom_id']) ? $this->info['default_view_uom_id'] : $this->info['UOM_ID'];
        $this->info['default_view_rate'] = !empty($this->info['default_view_rate']) ? $this->info['default_view_rate'] : 1;
        $this->info['family_id'] = !empty($this->info['family_id']) ? $this->info['family_id'] : NULL;
        $this->info['default_sales_uom'] = !empty($this->info['default_sales_uom']) ? $this->info['default_sales_uom'] : 0;
        $this->info['default_purchase_uom'] = !empty($this->info['default_purchase_uom']) ? $this->info['default_purchase_uom'] : 0;
        $this->info['print_uom_id'] = !empty($this->info['print_uom_id']) ? $this->info['print_uom_id'] : 0;
        $this->info['product_second_code'] = !empty($this->info['product_second_code']) ? $this->info['product_second_code'] : NULL;
        $this->info['recipe_qty'] = !empty($this->info['recipe_qty']) ? $this->info['recipe_qty'] : 1;
        $this->info['product_param1'] = !empty($this->info['product_param1']) ? $this->info['product_param1'] : '';
        $this->info['product_param2'] = !empty($this->info['product_param2']) ? $this->info['product_param2'] : '';
        $this->info['product_param3'] = !empty($this->info['product_param3']) ? $this->info['product_param3'] : '';
        $this->info['product_param4'] = !empty($this->info['product_param4']) ? $this->info['product_param4'] : '';

        //
        $data = [&$this->info['Product_Code'],
            &$this->info['Product_Arabic_Name'],
            &$this->info['Product_Name'],
            &$this->info['Category_ID'],
            &$this->info['Product_Reorder_Point'],
            &$this->info['Product_VAT'],
            &$this->info['vat_percent'],
            &$this->info['vat2_percent'],
            &$this->info['UOM_ID'],
            &$this->info['product_description'],
            &$this->info['product_color'],
            &$this->info['product_order'],
            &$this->info['logged_id'],
            &$this->info['move_scale'],
            &$this->info['is_card'],
            &$this->info['plu_type'],
            &$this->info['printer_id'],
            &$this->info['product_type'],
            &$this->info['Product_Limit_Discount'],
            &$this->info['group_account_id'],
            &$this->info['brand_id'],
            &$this->info['pur_cat_id'],
            &$this->info['link_note'],
            &$plu,
            &$current_date_time, &$this->info['section_id'], &$this->info['machine_type_id'],
            &$this->info['is_expiry'],
            &$this->info['force_change_price'],
            &$this->info['duration_reservation'],
            &$this->info['is_lot'],
            &$this->info['is_serial'],
            &$this->info['is_service'],
            &$this->info['is_ticket'],
            &$this->info['main_supplier_id'],
            &$this->info['default_view_uom_id'],
            &$this->info['default_view_rate'],
            &$this->info['family_id'], &$this->info['default_sales_uom'], &$this->info['default_purchase_uom'],
            &$this->info['product_second_code'],
            &$this->info['recipe_qty'], $this->info['product_param1'], $this->info['product_param2'],
            $this->info['product_param3'], $this->info['product_param4'], $this->info['print_uom_id'],&$this->info['is_rate'],&$this->info['current_branch_id']
            ,&$this->info['is_rate_type_one']
            ,&$this->info['is_rate_type_two']
            ,&$this->info['n_width']
            ,&$this->info['n_height']
            ,&$this->info['effect_qty_link_product']
            ,&$this->info['hide_pos_to_edit']
            ,&$this->info['positive_points']
            ,&$this->info['negative_points']

            ,&$this->info['Product_ID']];
        //        echo "<pre>";die(print_r($data));
        $this->db->prepare_Stmt('UPDATE
                                        tbl_stock_products
                                    SET
                                       Product_Code           =  ?,
                                       Product_Arabic_Name    =  ?,
                                       Product_Name           =  ?,
                                       Category_ID            =  ?,
                                       Product_Reorder_Point  =  ?,
                                       Product_VAT            =  ?,
                                       vat_percent            =  ?,
                                       vat2_percent            =  ?,
                                       UOM_ID                 =  ?,
                                       product_description    =  ?,
                                       product_color          =  ?,
                                       product_order          =  ?,
                                       Logged_ID              =  ?,
                                       on_scale               =  ?,
                                       is_tax                 =  ?,
                                       PLU_Type               =  ?,
                                       printer_id             =  ?,
                                       product_type           =  ?,
                                       Product_Limit_Discount =  ?,
                                       group_account_id       =  ?,
                                       brand_id               =  ?,
                                       pur_cat_id               =  ?,
                                       link_note              =  ?,
                                       Product_PLU            =  ?,
                                       date_time              =  ?,
                                       section_id             =  ?,
                                       machine_type_id        =  ?,
                                       is_expiry              =  ?,
                                       force_change_price     =  ?,
                                       duration_reservation   =  ?,
                                       is_lot                 =  ?,
                                       is_serial              =  ?,
                                       is_service             =  ?,
                                       is_ticket              =  ?,
                                       main_supplier_id       =  ?,
                                       default_view_uom_id    =  ?,
                                       default_view_rate      =  ?,
                                       family_id              =  ?,
                                       default_sales_uom      =  ?,
                                       default_purchase_uom   =  ?,
                                       product_second_code    =  ?,
                                       recipe_qty    =  ?,product_param1=?,product_param2=?,product_param3=?,product_param4=?,
                                       print_uom_id=?,
                                       is_rate=?,
                                       multi_branch_id = ?,
                                       is_rate_type_one = ?,
                                       is_rate_type_two = ?,
                                       n_width  = ?,
                                       n_height = ?,
                                       effect_qty_link_product =?,
                                       hide_pos1 = ?,
                                       positive_points = ?,
                                       negative_points = ?
                                    WHERE
                                        Product_ID            = ?', $data);
        $arr_prod = ['type' => 'prod', 'main_id' => $this->info['Product_ID'], 'action' => 1,
            'date_time' => $current_date_time, 'user_id' => smc_session()['user_logged_id']];
        CommonFunctions::add_user_log($arr_prod);



        $today = Date::getToday();
        $class_price_arr = array();
        //        $this->db->prepare_Stmt('delete pc from tbl_item_price_by_classes pc
        //            join tbl_pricing_class c using(Class_ID) where Product_ID = ? and type=0', [&$this->info['Product_ID']]);
        if (!empty($this->info['price_arr'])) {
            $classes = json_decode($this->info['price_arr'], true);
            foreach ($classes as $class) {
                $data = [&$class['class_id'], &$this->info['Product_ID'],
                    &$this->info['UOM_ID'], &$class['price'], &$class['currency_id'], &$today, &$this->info['logged_id'],
                    &$class['price'], &$this->info['logged_id']];

                $class_price_arr[$class['class_id']] = $class['price'];
                $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,
                        UOM_ID,Product_Price,Currency_ID,Pricing_Date,Logged_ID) '
                        . '                 VALUES(?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE Product_Price = ?,Logged_ID = ?', $data);

                //                $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,
                //                    UOM_ID,Product_Price,Currency_ID,Pricing_Date) '
                //                        . '                 VALUES(?,?,?,?,?,?)', $data);
                if (smc_session()['default_setting']['activate_price_log'] == 1) {
                    $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes_log (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,date_time,Logged_ID) '
                            . '                 VALUES(?,?,?,?,?,?,?)', [
                        &$class['class_id'], &$this->info['Product_ID'], &$this->info['UOM_ID'], &$class['price'], &$class['currency_id'], &$current_date_time, &$this->info['logged_id']]);
                }
            }
        }



        $this->db->prepare_Stmt('DELETE from tbl_uom_conversions where Product_ID = ?', [&$this->info['Product_ID']]);
        $barcode = !empty($this->info['Bar_Code']) ? ($this->info['Bar_Code'] != '' ? $this->info['Bar_Code'] : $this->info['Product_Code']) : $this->info['Product_Code'];
        $data_conv = [&$this->info['UOM_ID'], &$this->info['UOM_ID'], &$this->info['Product_ID'], &$barcode, &$this->info['additional_barcodes']];
        $this->db->prepare_Stmt('INSERT INTO tbl_uom_conversions 
                                                    (uom_from,
                                                    conversion_amount,
                                                    uom_to,
                                                    Product_ID,
                                                    is_default,
                                                    Bar_Code,
                                                    additional_barcodes
                                                    )
                                                    VALUES(?,1,?,?,1,?,?)
                                                    ', $data_conv);
        if (!empty($this->info['con'])) {
            $uom_conversions = json_decode($this->info['con'], true);
            foreach ($uom_conversions as $uoms) {
                if ($uoms['conversion_amount'] != '' && $uoms['uom_from'] != '') {
                    $uoms['additional_barcodes'] = trim(preg_replace('/\s+/', ',', $uoms['additional_barcodes']));

                    $is_default = ($uoms['uom_from'] == $uoms['uom_to']) ? 1 : 0;
                    $uoms['code'] = $uoms['code'] == '' ? NULL : $uoms['code'];
                    $data1 = [&$uoms['uom_from'], &$uoms['conversion_amount'], &$uoms['uom_to'], &$this->info['Product_ID'], &$is_default, &$uoms['code'], &$uoms['additional_barcodes']];

                    $this->db->prepare_Stmt('INSERT INTO tbl_uom_conversions (uom_from,conversion_amount,uom_to,Product_ID,is_default,Bar_Code,additional_barcodes) '
                            . '                 VALUES(?,?,?,?,?,?,?)', $data1);
                    foreach ($uoms['uom_prices'] as $uom_price) {

                        $data = [&$uom_price['class_id'], &$this->info['Product_ID'], &$uoms['uom_from'], &$uom_price['price'],
                            &$uom_price['currency_id'], &$today, &$uom_price['price'], &$this->info['logged_id']];
                        $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,Pricing_Date) '
                                . '                 VALUES(?,?,?,?,?,?) ON DUPLICATE KEY UPDATE Product_Price = ?,Logged_ID = ?', $data);
                    }
                }
            }
        }

        $this->db->prepare_Stmt('delete from tbl_products_link where main_product_id = ?', [&$this->info['Product_ID']]);

        if (!empty($this->info['in_item'])) {
            $in_products = json_decode($this->info['in_item'], true);
            //        echo"<pr>";die(print_r($out_products));
            foreach ($in_products as $in) {
                $in_qty = Product::getConvertedQuantity($in['sub_uom'], $in['sub_qty'], $in['sub_item']);
                $in_data = [&$this->info['Product_ID'], &$in['sub_item'], &$in_qty, &$in['sub_qty'], &$in['sub_uom']];
                $this->db->prepare_Stmt('insert into tbl_products_link (main_product_id,sub_product_id,quantity,operation,current_quantity,UOM_ID)
                                        values(?,?,?,"+",?,?)', $in_data);
            }
        }
        if (!empty($this->info['out_item'])) {
            $out_products = json_decode($this->info['out_item'], true);

            foreach ($out_products as $out) {
                $out_qty = Product::getConvertedQuantity($out['sub_uom'], $out['sub_qty'], $out['sub_item']);
                $in_data = [&$this->info['Product_ID'], &$out['sub_item'], &$out_qty, &$out['sub_qty'], &$out['sub_uom']];
                $this->db->prepare_Stmt('insert into tbl_products_link (main_product_id,sub_product_id,quantity,operation,current_quantity,UOM_ID)
                                        values(?,?,?,"-",?,?)', $in_data);
            }
        }

        $this->db->prepare_Stmt('delete from tbl_product_shelf where product_id = ?', [&$this->info['Product_ID']]);
        if (!empty($this->info['product_shelf'])) {
            $product_shelf = json_decode($this->info['product_shelf'], true);
            foreach ($product_shelf as $prd_shlf) {
                if (!empty($prd_shlf['shelf_depot_id'])) {
                    $shelf_depot_id = explode(',', $prd_shlf['shelf_depot_id']);
                    foreach ($shelf_depot_id as $depot_shlf) {
                        $data = [
                            &$this->info['Product_ID'],
                            &$depot_shlf,
                            &$prd_shlf['depot_id']
                        ];
                        $this->db->prepare_Stmt('insert into tbl_product_shelf (`product_id`, `shelf_depot_id`, `depot_id`) VALUES (?,?,?)', $data);
                    }
                }
            }
        }

        $this->db->prepare_Stmt('delete from tbl_product_add_ons where product_id = ? ', [&$this->info['Product_ID']]);
        if (!empty($this->info['add_ons'])) {
            $add_ons = json_decode($this->info['add_ons'], true);
            if (smc_session()['default_setting']['is_add_ons_active'] == 1 && !empty($add_ons)) {
                foreach ($add_ons as $details) {
                    $this->db->prepare_Stmt('INSERT INTO tbl_product_add_ons 
            SET
                                            product_add_ons_quantity = ?,
                                            add_ons_id = ?,
                                            product_id = ?', [&$details['product_add_ons_quantity'],
                        &$details['add_ons_id'],
                        &$this->info['Product_ID']
                    ]);
                    $product_add_ons_id = $this->db->id();
                    $product_add_ons = 'INSERT INTO tbl_meal_add_ons
            (meal_add_ons_quantity,add_ons_id,meal_id,meal_add_ons_id_offline,branch_id) '
                            . '                 VALUES(?,
                                    (SELECT  add_ons_id FROM tbl_add_ons WHERE add_ons_id_offline = ? and branch_id = "' . SMARTDINER_BRANCH_ID . '"),
                                    (SELECT  meal_id FROM tbl_meal WHERE meal_id_offline = "' . $this->info['Product_ID'] . '" and branch_id = "' . SMARTDINER_BRANCH_ID . '"),"' . $product_add_ons_id . '" ,"' . SMARTDINER_BRANCH_ID . '")';
                    $sync_query .= $this->db->is_logged_query($product_add_ons, [$details['product_add_ons_quantity'],
                        $details['add_ons_id']]);
                }
            }
        }

        if (!empty($this->info['criteria'])) {
            $criterias = json_decode($this->info['criteria'], true);
            if (smc_session()['default_setting']['is_tag_active'] == 1 && !empty($criterias)) {
                $current_ids = json_decode($this->info['criteria_ids'], true);
                $criteria_cond = !empty($current_ids) ? ' and criteria_id not in(' . implode(',', $current_ids) . ') ' : '';
                $this->db->prepare_Stmt('delete from tbl_product_criteria 
            where  Product_ID = ? ' . $criteria_cond, [&$this->info['Product_ID']]);
                foreach ($criterias as $criteria) {
                    $max_count = $criteria['criteria_type'] == 1 ? $criteria['criteria_max_count'] : 1;
                    $criteria_data = [&$criteria['criteria_name'], &$criteria['criteria_type'], &$max_count, &$this->info['Product_ID']];
                    $criteria_id = $criteria['criteria_id'];
                    if ($criteria['criteria_id'] == 0) {
                        $this->db->prepare_Stmt("INSERT INTO tbl_product_criteria (criteria_name,criteria_type,criteria_max_count,is_required,Product_ID) 
                                                            VALUES(?,?,?,0,?)
                    ", $criteria_data);
                        $criteria_id = $this->db->id();
                    } else {
                        $this->db->prepare_Stmt("update tbl_product_criteria set criteria_name = ?,criteria_type = ?,criteria_max_count =?,is_required =0 ,Product_ID = ? where criteria_id = ?
                    ", [&$criteria['criteria_name'], &$criteria['criteria_type'], &$max_count,
                            &$this->info['Product_ID'], &$criteria['criteria_id']]);
                    }
                    $current_details_ids = $criteria['criteria_detail_ids'];
                    $criteria_detail_cond = !empty($current_details_ids) ? ' and criteria_detail_id not in(' . implode(',', $current_details_ids) . ') ' : '';

                    $this->db->prepare_Stmt('delete from tbl_product_criteria_detail 
                            where  criteria_id = ? ' . $criteria_detail_cond, [&$criteria_id]);

                    foreach ($criteria['criteria_details'] as $details) {
                        $criteria_detail_id = $details['criteria_detail_id'];
                        if ($criteria_detail_id == 0) {
                            $this->db->prepare_Stmt("INSERT INTO  tbl_product_criteria_detail (criteria_detail_name,criteria_detail_price,criteria_id) 
                                                            VALUES(?,?,?)
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$criteria_id]);
                        } else {
                            $this->db->prepare_Stmt("update  tbl_product_criteria_detail set criteria_detail_name = ?,criteria_detail_price =? ,criteria_id =? where criteria_detail_id =?  
                    ", [&$details['criteria_detail_name'], &$details['criteria_detail_price'], &$criteria_id, &$criteria_detail_id]);
                        }
                    }
                }
            }
        }

        $delete_add_ons_data = 'delete from tbl_meal_add_ons where  meal_id = (select meal_id from tbl_meal where meal_id_offline = ? and branch_id =  "' . SMARTDINER_BRANCH_ID . '") and branch_id = "' . SMARTDINER_BRANCH_ID . '"';
        $sync_query .= $this->db->is_logged_query($delete_add_ons_data, [$this->info['Product_ID']]);

        if (!empty($this->info['prop_arr'])) {
            $prop_arr = json_decode($this->info['prop_arr'], true);
            $prop_ids = json_decode($this->info['prop_ids'], true);
            $prop_cond = !empty($prop_ids) ? ' and property_id not in(' . implode(',', $prop_ids) . ') ' : '';
            $this->db->prepare_Stmt('delete from tbl_stock_product_properties 
            where  Product_ID = ? ' . $prop_cond, [&$this->info['Product_ID']]);
            foreach ($prop_arr as $prop) {
                if (empty($prop['property_id'])) {
                    $this->db->prepare_Stmt('INSERT INTO `tbl_stock_product_properties`( `property_name`,
                `Product_ID`) VALUES (?,?)', [&$prop['property_name'], &$this->info['Product_ID']]);
                } else {
                    $this->db->prepare_Stmt('update `tbl_stock_product_properties` set  `property_name` = ? 
                where `Product_ID`=? and property_id = ?', [&$prop['property_name'], &$this->info['Product_ID'], &$prop['property_id']]);
                }
            }
        }

        if (array_key_exists('current_entry_id', $this->info)) {
            if ($this->info['current_entry_id'] == 0) {
                $this->db->prepare_Stmt('update `tbl_stock_products_parts` set  `part_note` = ? 
                where Product_ID = 0 and part_product_id = ? ', [&$this->info['part_note'], &$this->info['Product_ID']]);
            } else {
                $this->db->prepare_Stmt('update `tbl_stock_products_parts` set  `part_note` = ? 
                where `part_id`=? ', [&$this->info['part_note'], &$this->info['current_entry_id']]);
            }
        }
        $this->db->prepare_Stmt('delete d.*,p.* from tbl_product_options p 
            join tbl_product_option_details d using(option_id) where p.product_id = "' . $this->info['Product_ID'] . '"');
        if (!empty($this->info['optionals'])) {
            $optionals = json_decode($this->info['optionals'], true);
            foreach ($optionals as $option) {
                $data = [$this->info['Product_ID'], $option['quantity'], $option['is_required']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_options`(' . (!empty($option['option_id']) ? 'option_id,' : '') . ' `product_id`, `quantity`,
                   `is_required`, `operation`) values(' . (!empty($option['option_id']) ? $option['option_id'] . ',' : '') . '?,?,?,"-")', $data);
                $option_id = $this->db->id();
                if (!empty($option['details'])) {
                    foreach ($option['details'] as $det) {
                        $det_arr = [$option_id, $det['product_id'], $det['uom_id']];
                        $this->db->prepare_Stmt('INSERT INTO `tbl_product_option_details`( `option_id`,
                        `sub_product_id`, `UOM_ID`) values(?,?,?)', $det_arr);
                    }
                }
            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
            $uploaddir = upload_path . 'products_photos/';
            $this->SaveUploadedPhoto("image_file", $uploaddir . $this->info['Product_ID'] . '.jpg');
            if ($this->info['move_scale'] == 1 && smc_session()['activate_scale'] == 1) {
                foreach ($scales_arr as $scale_row) {
                    $class_id = $scale_row['class_id'];
                    $prod_price = (empty($class_id) ? $this->info['price'] : $class_price_arr[$class_id]);
                    $scale_prod_arr = array(array('Product_PLU' => $this->info['Product_PLU'], 'Product_Name' => $this->info['Product_Name'],
                            'Product_Description' => $this->info['Product_Arabic_Name'], 'Product_Code' => $this->info['Bar_Code']/* printed on barcode */
                            , 'PLU_Type' => $this->info['plu_type'], 'Product_Price' => $prod_price));
                    $scale = scale::scale_obj($scale_row);
                    $scale->register_products($scale_prod_arr);
                }
            }
            if (smc_session()['default_setting']['is_sync_active'] == 1) {
                //                if(isset($_FILES['image_file']['name']) &&  $_FILES['image_file']['name'] != ""){
                //                    $image_path = 'uploads/products_photos/'. $this->info['Product_ID'] . '.jpg';
                //                    $this->db->is_logged_image($image_path,'edit');
                //                }
                $class_id = !empty(smc_session()['default_setting']['smart_diner_app_class_id']) ? smc_session()['default_setting']['smart_diner_app_class_id'] : smc_session()['default_setting']['pricing_class_id'];
                //                $price_query = $this->db->query('select c.Product_Price  from tbl_item_price_by_classes c inner join tbl_stock_products p
                //                                             on c.Product_ID = p.Product_ID and c.UOM_ID = p.UOM_ID 
                //                                             where p.Product_ID =  "' . $this->info['Product_ID'] . '" 
                //                                             and c.Class_ID = "' . $class_id . '"');
                //                $online_product_price = $this->db->assoc($price_query)['Product_Price'];
                $online_product_price = self::get_product_price($this->info['Product_ID'], $class_id, $this->info['UOM_ID']);

                $product_data = 'Update tbl_meal
                                                    set meal_name = ?,
                                                        meal_price = ?,
                                                        meal_description = ?,
                                                        category_id = (SELECT  category_id FROM tbl_category WHERE category_id_offline = ? and branch_id = ?),
                                                        meal_image = ?
                                    where
                                                    meal_id_offline  = ?
                                    and             branch_id = ?';
                $this->db->is_logged_data($product_data, [$this->info['Product_Name'],
                    $online_product_price,
                    $this->info['product_description'],
                    $this->info['Category_ID'],
                    SMARTDINER_BRANCH_ID,
                    '',
                    $this->info['Product_ID'],
                    SMARTDINER_BRANCH_ID]);
                $criteria_query = $this->db->query('select * from tbl_product_criteria where Product_ID ="' . $this->info['Product_ID'] . '"');
                $delete_criteria_online = 'Delete from tbl_meal_criteria where meal_id = (select meal_id from tbl_meal where meal_id_offline = ? and branch_id = ?)';
                $this->db->is_logged_data($delete_criteria_online, [$this->info['Product_ID'], SMARTDINER_BRANCH_ID]);
                while ($row = $this->db->assoc($criteria_query)) {
                    $criteria_data = 'INSERT INTO tbl_meal_criteria (
                                                    criteria_name,
                                                    criteria_type,
                                                    criteria_max_count,
                                                    is_required,
                                                    meal_id,
                                                    criteria_id_offline,
                                                    branch_id) 
                                            VALUES(?,?,?,?,
                                            (select meal_id from tbl_meal where meal_id_offline = ? and branch_id = ?),
                                            ?,?)';
                    $this->db->is_logged_data($criteria_data, [$row['criteria_name'], $row['criteria_type'],
                        $row['criteria_max_count'], $row['is_required'],
                        $this->info['Product_ID'], SMARTDINER_BRANCH_ID, $row['criteria_id'], SMARTDINER_BRANCH_ID]);
                }
                $criteria_details_query = $this->db->query('select details.* from tbl_product_criteria_detail details inner join tbl_product_criteria criteria 
                on  details.criteria_id = criteria.criteria_id
                where criteria.Product_ID ="' . $this->info['Product_ID'] . '" ');
                while ($row2 = $this->db->assoc($criteria_details_query)) {
                    $criteria_detail_data = 'INSERT INTO tbl_meal_criteria_detail (
                                                            criteria_detail_name,
                                                            criteria_detail_price,
                                                            criteria_id,
                                                            criteria_detail_id_offline,
                                                            branch_id) 
                                                    VALUES(?,?,(select criteria_id from tbl_meal_criteria where criteria_id_offline=?  and branch_id =?),?,?)';
                    $this->db->is_logged_data($criteria_detail_data, [$row2['criteria_detail_name'], NULL, $row2['criteria_id'], SMARTDINER_BRANCH_ID, $row2['criteria_detail_id'], SMARTDINER_BRANCH_ID]);
                }
                if ($sync_query != '') {
                    $this->db->is_logged_file($sync_query);
                }
            }
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function checkIfPropertyUsed($ids) {
        //check if if property is used in tbl_product_property_values_details
        $property_values_query = $this->db->query('select * from tbl_product_property_values_details where property_id IN (' . $ids . ') limit 1');
        $property_values_count = $this->db->rowsno($property_values_query);
        if ($property_values_count > 0) {
            return true;
        }
        //check if if property is used in tbl_checklist_schedule
        $checklist_property_query = $this->db->query('select * from tbl_checklist_schedule where schedule_type_id =  2 and schedule_repeat_id IN (' . $ids . ') limit 1');
        $checklist_property_count = $this->db->rowsno($checklist_property_query);
        if ($checklist_property_count > 0) {
            return true;
        }
    }

    public function viewAvailableQuantity($product_id) {
        $available_quantity = 0;
        $query = $this->db->query('SELECT
                                        Product_Quantity 
                                    FROM 
                                        tbl_stock_products 
                                    WHERE 
                                        Product_ID = "' . $product_id . '" 
                                    AND
                                        Status_ID = 1');
        $row = $this->db->assoc($query);
        $available_quantity = $row['Product_Quantity'];
        return $available_quantity;
    }

    public function viewSoldQuantityByDate($product_id = null, $year = null, $month = null, $day = null, $date = null) {
        $condition = '';
        $data = array();
        if (!is_null($product_id))
            $condition .= ' AND p.Product_ID = "' . $product_id . '"';
        if (!is_null($year))
            $condition .= ' AND YEAR(i.Invoice_Date) = "' . $year . '"';
        if (!is_null($month))
            $condition .= ' AND MONTH(i.Invoice_Date) = "' . $month . '"';
        if (!is_null($day))
            $condition .= ' AND DAY(i.Invoice_Date) = "' . $day . '"';
        if (!is_null($date))
            $condition .= ' AND i.Invoice_Date = "' . $date . '"';
        $query = $this->db->query('SELECT
                                        SUM(p.Product_Quantity) AS Total_Quantity, SUM(p.Product_Total_Price) AS Total_Price
                                    FROM
                                        tbl_invoice_products_details p
                                    RIGHT JOIN
                                        tbl_invoices i
                                    ON
                                        p.Invoice_ID_Auto = i.Invoice_ID_Auto
                                    WHERE
                                     1=1' . $condition);
        $row = $this->db->assoc($query);
        $data = array(
            'Total_Quantity' => $row['Total_Quantity'],
            'Total_Price' => $row['Total_Price']
        );
        return $data;
    }

    public function viewSoldQuantity($product_id = null, $year = null, $month = null, $day = null, $type = 0, $IsActual = null, $from = null, $to = null) {
        $actQty = 0;
        $condition = ' ';
        $Actcondition = ' ';
        $data = array();
        if (!is_null($product_id))
            $condition .= ' AND p.Product_ID = "' . $product_id . '" ';
        if (!is_null($year))
            $condition .= 'AND YEAR(i.Invoice_Date) = "' . $year . '"';
        if (!is_null($month))
            $condition .= 'AND MONTH(i.Invoice_Date) = "' . $month . '"';
        if (!is_null($day))
            $condition .= 'AND DAY(i.Invoice_Date) = "' . $day . '"';
        $query = $this->db->query('SELECT
                                        SUM(p.Product_Quantity) AS Total_Quantity
                                    FROM
                                        tbl_invoice_products_details p
                                    RIGHT JOIN
                                        tbl_invoices i
                                    ON
                                        p.Invoice_ID_Auto = i.Invoice_ID_Auto
                                    WHERE
                                         1=1' . $condition);
        $row = $this->db->assoc($query);

        $data = $row['Total_Quantity'];
        return $data;
    }

    public function viewPurchaseQuantity($product_id = null, $year = null, $month = null, $day = null, $type = 0) {
        $condition = ' ';
        $data = array();
        if (!is_null($product_id))
            $condition .= ' AND d.Product_ID = "' . $product_id . '" ';
        if (!is_null($year))
            $condition .= 'AND YEAR(p.Purchase_Date) = "' . $year . '"';
        if (!is_null($month))
            $condition .= 'AND MONTH(p.Purchase_Date) = "' . $month . '"';
        if (!is_null($day))
            $condition .= 'AND DAY(p.Purchase_Date) = "' . $day . '"';
        $query = $this->db->query('SELECT
                                        SUM(d.Item_Quantity) AS Total_Quantity
                                    FROM
                                        tbl_inventory_purchase_items d
                                    RIGHT JOIN
                                        tbl_inventory_purchases p
                                    ON
                                        p.Purchase_ID = d.Purchase_ID
                                    WHERE
                                         1=1' . $condition);
        $row = $this->db->assoc($query);
        $data = $row['Total_Quantity'];
        return $data;
    }

    public function viewReturnQuantityByDate($product_id, $year = null, $month = null, $day = null) {
        $condition = '';
        $data = array();
        if (!is_null($year))
            $condition .= 'AND YEAR(i.Return_Invoice_Date) = "' . $year . '"';
        if (!is_null($month))
            $condition .= 'AND MONTH(i.Return_Invoice_Date) = "' . $month . '"';
        if (!is_null($day))
            $condition .= 'AND DAY(i.Return_Invoice_Date) = "' . $day . '"';
        $query = $this->db->query('SELECT
                                        SUM(r.Return_Product_Quantity) AS Total_Quantity, SUM(r.Return_Product_Total) AS Total_Price
                                    FROM
                                        tbl_accounting_return_items r
                                    RIGHT JOIN
                                        tbl_accounting_return_invoices i
                                    ON
                                        r.Return_Invoice_ID = i.Return_Invoice_ID
                                    WHERE
                                        Product_ID = "' . $product_id . '"
                                    AND
                                        Is_Customer_Invoice = 1' . $condition);
        $row = $this->db->assoc($query);
        $data = array(
            'Total_Quantity' => $row['Total_Quantity'],
            'Total_Price' => $row['Total_Price']
        );
        if (is_null($data['Total_Quantity'])) {
            $data['Total_Quantity'] = 0;
            $data['Total_Price'] = 0;
        }
        return $data;
    }

    public function viewBestCustomer($product_id) {
        $data = array();
        $query = $this->db->query('SELECT
                                        i.Customer_ID,c.Customer_Name,SUM(p.Product_Quantity) AS Sum_Product
                                    FROM
                                        tbl_invoice_products_details p
                                    RIGHT JOIN
                                        tbl_invoices i
                                    ON
                                        p.Invoice_ID_Auto = i.Invoice_ID_Auto
                                    LEFT JOIN
                                        tbl_customers c
                                    ON
                                        c.Customer_ID = i.Customer_ID
                                    WHERE
                                        p.Product_ID = "' . $product_id . '"
                                    AND 
                                        c.Status_ID = 1
                                   GROUP BY
                                        i.Customer_ID
                                    ORDER BY
                                       SUM(p.Product_Quantity) DESC
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        if (!empty($data)) {
            $data = array(array('Customer_ID' => 0,
                    'Customer_Name' => '',
                    'Sum_Product' => 0
            ));
        }
        return $data;
    }

    public function viewProductByCustomer($product_id, $customer_id) {
        $data = array();
        $query = $this->db->query('SELECT
                                        i.Customer_ID,c.Customer_Name,SUM(p.Product_Quantity) AS Sum_Product
                                    FROM
                                        tbl_invoice_products_details p
                                    RIGHT JOIN
                                        tbl_invoices i
                                    ON
                                        p.Invoice_ID = i.Invoice_ID
                                    LEFT JOIN
                                        tbl_customers c
                                    ON
                                        c.Customer_ID = i.Customer_ID
                                    WHERE
                                        Product_ID = "' . $product_id . '"
                                   AND
                                           i.Customer_ID = "' . $customer_id . '"
                                   AND  
                                        c.Status_ID = 1
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        if (count($data) == 0) {
            $data = array(array('Customer_ID' => 0,
                    'Customer_Name' => '',
                    'Sum_Product' => 0
            ));
        }
        return $data;
    }

    public function viewProductAveragePrice($product_id) {
        $average_unit_price = 0;
        $total_price = 0;
        $total_quantity = 0;
        $query = $this->db->query('SELECT
                                        i.Product_Total_Price,
                                        p.Currency_ID,
                                        i.Item_Quantity
                                    FROM
                                        tbl_inventory_purchase_items i
                                    LEFT JOIN
                                        tbl_inventory_purchases p
                                    ON
                                        i.Purchase_ID_Auto = p.Purchase_ID_Auto
                                    WHERE
                                        i.Product_ID = "' . $product_id . '"
                ');
        while ($row = $this->db->assoc($query)) {
            $price = CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Currency_ID'], $row['Product_Total_Price']);
            $total_price += $price;
            $total_quantity += $row['Item_Quantity'];
        }
        if ($total_quantity == 0)
            $total_quantity = 1;
        $average_unit_price = $total_price / $total_quantity;
        return $average_unit_price;
    }

    public function yearlyOrMonthlySoldQuantity($product_id, $year, $s_month = null) {
        $result = array();
        if (is_null($s_month)) {
            for ($month = 01; $month < 13; $month++) {
                $monthly_sold_quantity = self::viewSoldQuantityByDate($product_id, $year, $month);
                array_push($result, $monthly_sold_quantity);
                $monthly_sold_quantity = 0;
            }
        } else {
            for ($day = 01; $day < 32; $day++) {
                $daily_sold_quantity = self::viewSoldQuantityByDate($product_id, $year, $s_month, $day);
                array_push($result, $daily_sold_quantity);
                $daily_sold_quantity = 0;
            }
        }
        return $result;
    }

    /**
     * This function views Sold Quantity over years
     * @param  [[Type]] $product_id [[Description]]
     * @param  [[Type]] $start_year [[Description]]
     * @param  [[Type]] $end_year   [[Description]]
     * @return [[Type]] [[Description]]
     */
    public function viewSoldQuantityOverYears($product_id, $start_year, $end_year) {
        $result = array();
        for ($year = $start_year; $year < ($end_year + 1); $year++) {
            $yearly_sold_quantity = self::yearlyOrMonthlySoldQuantity($product_id, $year);
            array_push($result, $yearly_sold_quantity);
            $yearly_sold_quantity = 0;
        }
        return $result;
    }

    public function yearlyOrMonthlyReturnQuantity($product_id, $year, $s_month = null) {
        $result = array();
        if (is_null($s_month)) {
            for ($month = 01; $month < 13; $month++) {
                $monthly_return_quantity = self::viewReturnQuantityByDate($product_id, $year, $month);
                array_push($result, $monthly_return_quantity);
                $monthly_return_quantity = 0;
            }
        } else {
            for ($day = 01; $day < 32; $day++) {
                $daily_return_quantity = self::viewReturnQuantityByDate($product_id, $year, $s_month, $day);
                array_push($result, $daily_return_quantity);
                $daily_return_quantity = 0;
            }
        }
        return json_encode($result);
    }

    public function SoldQuantityPerDay($product_id, $year, $s_month = null, $type = 0, $IsActual = null) {
        $result = array();
        if (is_null($s_month)) {
            for ($month = 01; $month < 13; $month++) {
                $monthly_sold_quantity = self::viewSoldQuantity($product_id, $year, $month, null, $type, $IsActual);
                array_push($result, $monthly_sold_quantity);
                $monthly_sold_quantity = 0;
            }
        } else {
            for ($day = 01; $day < 32; $day++) {
                $daily_sold_quantity = self::viewSoldQuantity($product_id, $year, $s_month, $day, $type, $IsActual);
                array_push($result, $daily_sold_quantity);
                $daily_sold_quantity = 0;
            }
        }
        return $result;
    }

    public function PurchaseQuantityPerDay($product_id, $year, $s_month = null, $type = 0) {
        $result = array();
        if (is_null($s_month)) {
            for ($month = 01; $month < 13; $month++) {
                $monthly_purchase_quantity = self::viewPurchaseQuantity($product_id, $year, $month, null, $type);
                array_push($result, $monthly_purchase_quantity);
                $monthly_purchase_quantity = 0;
            }
        } else {
            for ($day = 01; $day < 32; $day++) {
                $daily_purchase_quantity = self::viewPurchaseQuantity($product_id, $year, $s_month, $day, $type);
                array_push($result, $daily_purchase_quantity);
                $daily_purchase_quantity = 0;
            }
        }
        return $result;
    }

    public function viewSoldQuantityPerCustomer($product_id, $customer_id, $year = null, $month = null, $day = null) {
        $condition = '';
        $data = array();
        if (!is_null($year))
            $condition .= 'AND YEAR(i.Invoice_Date) = "' . $year . '"';
        if (!is_null($month))
            $condition .= 'AND MONTH(i.Invoice_Date) = "' . $month . '"';
        if (!is_null($day))
            $condition .= 'AND DAY(i.Invoice_Date) = "' . $day . '"';
        $query = $this->db->query('SELECT
                                       i.Customer_ID, SUM(p.Product_Quantity) AS Total_Quantity
                                    FROM
                                        tbl_invoice_products_details p
                                    RIGHT JOIN
                                        tbl_invoices i
                                    ON
                                        p.Invoice_ID_Auto  = i.Invoice_ID_Auto
                                    LEFT JOIN
                                        tbl_customers c
                                    ON
                                        c.Customer_ID = i.Customer_ID
                                    WHERE
                                        i.Customer_ID = "' . $customer_id . '"
                                    AND 
                                        c.Status_ID = 1
                                    AND
                                        Product_ID = "' . $product_id . '"' . $condition);
        $row = $this->db->assoc($query);
        $data = $row['Total_Quantity'];
        return $data;
    }

    public function SoldQuantityPerCustomer($product_id, $customer_id, $year, $s_month = null) {
        $result = array();
        if (is_null($s_month)) {
            for ($month = 01; $month < 13; $month++) {
                $monthly_sold_quantity = self::viewSoldQuantityPerCustomer($product_id, $customer_id, $year, $month);
                array_push($result, $monthly_sold_quantity);
                $monthly_sold_quantity = 0;
            }
        } else {
            for ($day = 01; $day < 32; $day++) {
                $daily_sold_quantity = self::viewSoldQuantityPerCustomer($product_id, $customer_id, $year, $s_month, $day);
                array_push($result, $daily_sold_quantity);
                $daily_sold_quantity = 0;
            }
        }
        return $result;
    }

    //    public function SoldQuantityPerYear($product_id, $year, $s_month = null) {
    //        $result = array();
    //        if (is_null($s_month)) {
    //            for ($month = 01; $month < 13; $month++) {
    //                $monthly_sold_quantity = self::viewSoldQuantity($product_id, $year, $month);
    //                if (is_null($monthly_sold_quantity))
    //                    $monthly_sold_quantity = 0;
    //                array_push($result, $monthly_sold_quantity);
    //                $monthly_sold_quantity = 0;
    //            }
    //        }
    //        //        else {
    //        //            for ($day=01; $day<32; $day++) {
    //        //                $daily_sold_quantity = self::viewSoldQuantity($product_id, $year, $s_month, $day);
    //        //                array_push($result,$daily_sold_quantity);
    //        //                $daily_sold_quantity = 0;
    //        //            }
    //        //        }
    //        return $result;
    //    }

    /**
     * Generic function to get an uploaded $_FILE[name_of_file] and save it to a specific path
     * @param [[Type]] $FileName The name of the input[file] tag that is assigned in the client-side
     * @param [[Type]] $SavePath Destination path
     */
    public function SaveUploadedPhoto($FileName, $SavePath, $is_delete_file = true) {
        if (!isset($_FILES[$FileName]))
            return false;
        $SaveToPath = substr($SavePath, 0, strrpos($SavePath, "/") + 1);
        $SaveAsFile = substr($SavePath, strrpos($SavePath, "/") + 1);
        $SaveAsExtention = explode(".", $SaveAsFile);
        $SaveAsExtention = strtolower($SaveAsExtention[count($SaveAsExtention) - 1]);
        $SaveAsFile = substr($SaveAsFile, 0, strrpos($SaveAsFile, "."));
        $fileType = explode(".", basename($_FILES[$FileName]['name']));
        $fileType = strtolower($fileType[count($fileType) - 1]);
        $DestinationFile = $SaveToPath . $SaveAsFile . ".";
        if (file_exists($DestinationFile . $fileType))
            unlink($DestinationFile . $fileType);
        if ($is_delete_file) {
            move_uploaded_file($_FILES[$FileName]['tmp_name'], $DestinationFile . $fileType);
        } else {
            copy($_FILES[$FileName]['tmp_name'], $DestinationFile . $fileType);
        }


        if ($fileType == "png" && $SaveAsExtention == "jpg") {
            if (file_exists($DestinationFile . "jpg"))
                unlink($DestinationFile . "jpg");
            $image = imagecreatefrompng($DestinationFile . $fileType);
            imagejpeg($image, $DestinationFile . $SaveAsExtention, 100);
            imagedestroy($image);
            if (file_exists($DestinationFile . $fileType))
                unlink($DestinationFile . $fileType);
        }
    }

    public function viewListVendorPurchaseByProduct($product_id) {
        $data = array();
        $query = $this->db->query('SELECT
                                        s.Supplier_Name,
                                        i.Purchase_Date,
                                        p.Item_Quantity,
                                        p.Item_Price,
                                        i.Currency_ID,
                                        c.Currency_Symbol
                                    FROM
                                        tbl_inventory_purchase_items p
                                    LEFT JOIN
                                        tbl_inventory_purchases i
                                    ON
                                        p.Purchase_ID_Auto = i.Purchase_ID_Auto
                                    LEFT JOIN
                                        tbl_stock_suppliers s
                                    ON
                                        i.Supplier_ID = s.Supplier_ID
                                    LEFT JOIN
                                        tbl_common_currency c
                                    ON
                                        i.Currency_ID = c.Currency_ID
                                    WHERE
                                        Product_ID = "' . $product_id . '"
                                    AND 
                                        s.Status_ID = 1
                ');
        while ($row = $this->db->assoc($query)) {
            $row['Default_Currency_Price'] = CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Currency_ID'], $row['Item_Price']);
            $row['Default_Currency_Symbol'] = CurrencyFactory::getDefaultCurrencySymbol();
            $data[] = $row;
        }
        return $data;
    }

    public function viewExistingProduct($name) {
        $query = $this->db->query('SELECT 
                                            * 
                                        FROM 
                                            tbl_stock_products
                                        WHERE 
                                            Product_Code = "' . $name . '"
                                        AND 
                                            Status_ID = 1
			     ');
        $row = $this->db->assoc($query);
        if (!empty($row))
            return false;
        else
            return true;
    }

    public function getFirstItem($cat) {
        $data = array();

        $query = $this->db->query('SELECT
                                    Product_ID AS ID
                                FROM
                                    tbl_stock_products
                                WHERE 
                                    Status_ID = 1
                                ORDER BY
                                    Product_ID
                                LIMIT 1
        ');


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

    public function getClasses() {
        $data = array();
        $query = $this->db->query('SELECT *
                                    FROM
                                        tbl_pricing_class where type=0
                                ');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    //    public function getItemsToAdjustPrice($class = null) {
    //        $data = array();
    //        $condition = '';
    //        $select = '';
    //        $class_query = $this->db->query('SELECT * FROM tbl_item_price_by_classes WHERE Class_ID = "' . $class . '"');
    //        $class_exist = $this->db->assoc($class_query);
    //        if (!empty($class_exist)) {
    //            $condition .= ' LEFT JOIN
    //                                            tbl_item_price_by_classes pc
    //                                        ON
    //                                            pc.Product_ID = p.Product_ID
    //                                        LEFT JOIN
    //                                            tbl_pricing_class c
    //                                        ON
    //                                            c.Class_ID = pc.Class_ID
    //
    //                                        LEFT JOIN
    //                                            tbl_common_currency cu
    //                                        ON
    //                                            cu.Currency_ID = pc.Currency_ID
    //                                        WHERE pc.Class_ID = "' . $class . '"';
    //            $select .= 'pc.Product_Price';
    //        } else
    //            $select .= 'p.Product_Price';
    //
    //        $products = $this->db->query('SELECT 
    //                                            p.Product_ID AS ID,
    //                                            p.Product_Code AS Code,
    //                                            p.Product_Name AS Name,
    //                                            ' . $select . ' AS Price
    //                                        FROM
    //                                            tbl_stock_products p
    //
    //                                        ' . $condition);
    //
    //        while ($productList = $this->db->assoc($products)) {
    //            $data[] = $productList;
    //        }
    //
    //
    //        return $data;
    //    }

    public function AdjustItemPrices() {
        $this->db->query('START TRANSACTION');
        $today = Date::getToday();
        $current_date_time = date('Y-m-d H:i:s');

        $class_arr = array();

        foreach ($this->info['Products'] as $item) {
            if (!isset($class_arr[$item['Class_ID']])) {
                $query_class = $this->db->query('select Currency_ID from tbl_pricing_class where Class_ID = "' . $item['Class_ID'] . '"');
                $class_arr[$item['Class_ID']] = $this->db->assoc($query_class)['Currency_ID'];
            }
            $class_currency = $class_arr[$item['Class_ID']];
            $data = [&$item['Class_ID'],
                &$item['ID'],
                &$item['Price'],
                &$item['uom'],
                &$class_currency,
                &$today,
                &$this->info[0],
                &$item['Price'],
                &$item['uom'],
                &$this->info[0]
            ];
            $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes (Class_ID,Product_ID,' . (empty($this->info['is_disc']) ? 'Product_Price' : 'product_disc') . ',UOM_ID,Currency_ID,Pricing_Date,Logged_ID) '
                    . '                 VALUES(?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE ' . (empty($this->info['is_disc']) ? 'Product_Price' : 'product_disc') . ' = ?,UOM_ID = ?,Logged_ID = ?', $data);

            if (smc_session()['default_setting']['activate_price_log'] == 1) {
                $this->db->prepare_Stmt('INSERT INTO tbl_item_price_by_classes_log (Class_ID,Product_ID,UOM_ID,Product_Price,Currency_ID,date_time,Logged_ID) '
                        . '                 VALUES(?,?,?,?,?,?,?)', [
                    &$item['Class_ID'], &$item['ID'], &$item['uom'], &$item['Price'],
                    &$class_currency, &$current_date_time, &$this->info[0]]);
            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    //    public function getProductsForCustomer($classID = null, $cmd, $term, $depot_id = null, $cat_id = null, $type = null, $customer_id = null) {
    //        $data = array();
    //        $condition = ' ';
    //        $dep_cond = ' ';
    //        $is_ttc = 0;
    //        if (!empty($classID)) {
    //            $query_class = $this->db->query('select is_ttc from tbl_pricing_class where Class_ID = "' . $classID . '"');
    //            $is_ttc = $this->db->assoc($query_class)['is_ttc'];
    //        }
    //        if ($cmd == 1) {
    //            $condition .= ' AND concat(",",Bar_Code,",",additional_barcodes,",") LIKE "%,%' . smc_escape($term) . '%,%" ';
    //        } else if ($cmd == 2) {
    //            if (smc_session()['default_setting']['search_product_by_cat'] == 1) {
    //                $condition .= ' AND ( concat (cat.Cat_Name," " ,p.Product_Name) LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" or concat (cat.Cat_Name," " ,p.Product_Code) LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%")';
    //            } else {
    //                $condition .= ' AND ( p.Product_Name LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" or  p.Product_Code LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%")';
    //            }
    //        }
    //
    //        if (!is_null($depot_id)) {
    //            $dep_cond = 'left  join tbl_stock_product_location l on l.Location_Product_ID = p.Product_ID 
    //                and l.Product_Depot_ID = "' . $depot_id . '"';
    //        }
    //        if (!is_null($cat_id)) {
    //            $condition .= ' AND p.Category_ID = "' . $cat_id . '"';
    //        }
    //        if (!is_null($type)) {
    //            $condition .= ' and p.Product_Type in(0,' . $type . ')';
    //        }
    //        if (!empty($this->info['Status_ID'])) {
    //            $condition .= ' and p.Status_ID = 1 ';
    //        }
    //        if (!empty($this->info['is_edited'])) {
    //            $condition .= ' and (p.Status_ID = 1 or (p.Status_ID = 0 and p.Product_ID = "' . $this->info['is_edited'] . '") )';
    //        }
    //        $pids = array();
    //        $query = $this->db->query('SELECT
    //                                        p.Product_ID AS ID,
    //                                        Bar_Code,
    //                                        p.Product_Code AS Code,
    //                                        ' . (smc_session()['default_setting']['search_product_by_cat'] == 1 ? 'concat(cat.Cat_Name,": ")' : ' "" ') . ' as Cat_Name,
    //                                        p.Product_Name AS Name,
    //                                        ' . (!is_null($depot_id) ? 'if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)' : 'p.Product_Quantity') . ' AS Quantity,
    //                                        ' . (!is_null($classID) ? "pc.Product_Price AS Price," : "") . '
    //                                        p.Product_VAT AS VAT,
    //                                        p.vat_percent,
    //                                        p.is_tax,
    //                                        p.UOM_ID,
    //                                        ' . (!is_null($classID) ? "pc.Currency_ID," : "") . '
    //                                        ' . ($cmd == 1 ? 'uom_from' : ' GROUP_CONCAT(uom_from separator "/")') . ' AS Product_UOM,
    //                                        c.Currency_Symbol,
    //                                        p.Status_ID,
    //                                        p.Product_Limit_Discount,p.is_expiry
    //
    //                                    FROM
    //                                        tbl_stock_products p
    //                                        ' . (!is_null($classID) ?
    //                        "LEFT JOIN
    //                                        tbl_item_price_by_classes pc
    //                                    ON
    //                                       ( p.Product_ID = pc.Product_ID and pc.UOM_ID = p.UOM_ID AND pc.Class_ID = '" . $classID . "')" : "") . '
    //                                    LEFT JOIN 
    //                                        tbl_common_currency c
    //                                    ON
    //                                        pc.Currency_ID = c.Currency_ID   
    //                                    ' . (smc_session()['default_setting']['search_product_by_cat'] == 1 ?
    //                        ' inner join tbl_product_cat cat on cat.Cat_ID = p.Category_ID ' : '') . '
    //                                    inner JOIN 
    //                                        uom_conversions u 
    //                                    ON 
    //                                        p.Product_ID = u.Product_ID
    //                                    ' . $dep_cond . '
    //
    //                                    WHERE
    //
    //                                        1=1 ' . $condition . '
    //                                    ' . ($cmd == 1 ? '' : ' GROUP BY u.Product_ID ') . '
    //                                    LIMIT 60
    //                                ');
    //        while ($row = $this->db->assoc($query)) {
    //            $row['Price']=self::get_product_price($row['ID'],$classID,$row['UOM_ID']);
    //            $row['ttc_price'] = $row['Price'];
    //            if ($is_ttc == 1) {
    //                $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
    //            }
    //            $row['LAST_COST'] = CommonBusiness::viewLastProductCost($row["ID"]);
    //            if (!is_null($customer_id) && $this->perm->hasPermission('view_sales_last_price')) {
    //                $row['last_price'] = CommonBusiness::viewLastProductCustomerClassPrice($row["ID"], $customer_id, $classID);
    //            } else {
    //                $row['last_price'] = 0;
    //            }
    //            $row['loc'] = '';
    //            if ($cmd == 1) {
    //                $data[] = $row;
    //            } else {
    //                $pids[] = $row['ID'];
    //                $data[$row['ID']] = $row;
    //            }
    //        }
    //
    //        if (!is_null($depot_id) && smc_session()['default_setting']['display_shelf_locations'] == 1) {
    //            $pids_arr = implode(',', $pids);
    //
    //            $query_dep = $this->db->query('select GROUP_CONCAT(d.shelf_name separator ",") as loc,s.product_id
    //                from tbl_product_shelf s
    //                join tbl_shelfs_depot d on s.shelf_depot_id = d.shelf_depot_id 
    //                where s.product_id in (' . $pids_arr . ') and s.depot_id = "' . $depot_id . '" 
    //                    group by s.product_id');
    //            while ($row = $this->db->assoc($query_dep)) {
    //                $data[$row['product_id']]['loc'] = $row['loc'];
    //            }
    //        }
    //        if ($cmd != 1) {
    //            $pids_arr = implode(',', $pids);
    //            $query_barcode = $this->db->query('SELECT `Bar_Code`,Product_ID FROM `tbl_uom_conversions` WHERE `Product_ID` in (' . $pids_arr . ') and Is_default = 1');
    //            while ($brow = $this->db->assoc($query_barcode)) {
    //                $data[$brow['Product_ID']]['Bar_Code'] = $brow['Bar_Code'];
    //            }
    //        }
    //
    //        return $data;
    //    }
    public function getProductsForCustomer($classID = null, $cmd, $term, $depot_id = null, $cat_id = null, $type = null, $customer_id = null, $supp_class = '', $is_sales = 0, $is_purchase = 0) {
        $data = array();
        $condition = ' ';
        $dep_cond = ' ';
        $is_ttc = 0;
        $tax_amount = 0;
        $curr_symbol = $curr_id = '';
        $brand_condition = '';
        $supp_curr_id = 0;
        $cond_code = '';
        $code_columns = '';
        $person_code_cond = '';
        $prod_ids = array();
        if (!is_null($customer_id) && $is_sales == 1)
            $cond_code .= ' and customer_id = "' . $customer_id . '"';
        if (!is_null($customer_id) && $is_purchase == 1)
            $cond_code .= ' and supplier_id = "' . $customer_id . '"';
        if ($cmd == 3) {//case of customer/supplier codes
            $query = $this->db->query('select * from tbl_cust_supp_prod_codes 
                where product_code like "%' . smc_escape($term) . '%" ' . $cond_code);
            while ($row = $this->db->assoc($query)) {
                $prod_ids[$row['product_id']] = $row;
            }
            $person_code_cond .= ' left join tbl_cust_supp_prod_codes pcode 
                on pcode.product_id = p.Product_ID';
            if (!is_null($customer_id) && $is_sales == 1)
                $person_code_cond .= ' and customer_id = "' . $customer_id . '" ';
            if (!is_null($customer_id) && $is_purchase == 1)
                $person_code_cond .= ' and supplier_id = "' . $customer_id . '" ';
            $code_columns .= ',pcode.product_code as person_code ';
            if (empty($prod_ids))
                return $data;
            $condition .= ' and p.Product_ID in (' . implode(',', (array_keys($prod_ids))) . ') ';
        }else if ($cmd == 99) {//case of product id from libs\Common\SettingClass.php -> function enableDisableItem -- enable_when_disable_item_qty_zero
            $condition .= ' AND  p.Product_ID = '.$term. '  ';
        }


        if (smc_session()['default_setting']['show_product_brand_invoice'] == 1) {
            $brand_condition = '  or concat (brand.brand_name," " ,p.Product_Name) LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" or concat (brand.brand_name," " ,' . (smc_session()['default_setting']['activate_search_product_second_code'] == 1 ? 'p.product_second_code' : 'p.Product_Code') . ') LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" ';
        }
        if (!empty($classID)) {
            $query_class = $this->db->query('select Currency_ID, is_ttc,tax_amount from tbl_pricing_class where Class_ID = "' . $classID . '"');
            $class_row = $this->db->assoc($query_class);
            $is_ttc = $class_row['is_ttc'];
            $curr_id = $class_row['Currency_ID'];
            $tax_amount = $class_row['tax_amount'];
            $curr_symbol = CurrencyFactory::getCurrencySymbol($curr_id);
        }
        if (!empty($supp_class)) {
            $query_class = $this->db->query('select Currency_ID, is_ttc,tax_amount from tbl_pricing_class where Class_ID = "' . $supp_class . '"');
            $class_row = $this->db->assoc($query_class);
            $supp_curr_id = $class_row['Currency_ID'];
        }
        if ($cmd == 1) {//case of barcode
            $condition .= ' AND concat(",",Bar_Code,",",additional_barcodes,",") LIKE "%,%' . smc_escape($term) . '%,%" ';
        } else if ($cmd == 2) {//case of product code and name
            if (smc_session()['default_setting']['search_product_by_cat'] == 1) {
                $condition .= ' AND ( concat (cat.Cat_Name," " ,p.Product_Name) LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" or concat (cat.Cat_Name," " ,' . (smc_session()['default_setting']['activate_search_product_second_code'] == 1 ? 'p.product_second_code' : 'p.Product_Code') . ') LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%"  ' . ($brand_condition) . ') ';
            } else {
                $condition .= ' AND ( p.Product_Name LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" or  ' . (smc_session()['default_setting']['activate_search_product_second_code'] == 1 ? 'p.product_second_code' : 'p.Product_Code') . '  LIKE "%' . smc_escape(str_replace(" ", "%", trim($term))) . '%" ' . $brand_condition . ')';
            }
        }

        if (!is_null($depot_id)) {
            $dep_cond = 'left  join tbl_stock_product_location l on l.Location_Product_ID = p.Product_ID 
                and l.Product_Depot_ID = "' . $depot_id . '"';
        }
        if (!is_null($cat_id)) {
            $condition .= ' AND p.Category_ID = "' . $cat_id . '"';
        }
        if (!is_null($type)) {
            $condition .= ' and p.Product_Type in(0,' . $type . ')';
        }
        if (!empty($this->info['Status_ID'])) {
            $condition .= ' and p.Status_ID = 1 ';
        }
        if (!empty($this->info['is_edited'])) {
            $condition .= ' and (p.Status_ID = 1 or (p.Status_ID = 0 and p.Product_ID = "' . $this->info['is_edited'] . '") )';
        }
        if (!is_null($customer_id) && $is_purchase == 1 && smc_session()['default_setting']['purchase_restrict_product_supplier'] == 1) {
            $condition.=' and p.main_supplier_id = "' . $customer_id . '" ';
        }

        if($this->perm->hasPermission('Branches')){
             $condition .= '';
        }else{
            $condition .= ' and (multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '" ) ' ;
        }


        $pids = array();
        $query = $this->db->query('SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate,
                                        p.n_width,
                                        p.n_height,
                                        p.branch_id,
                                        Bar_Code,
                                        p.Product_Code AS Code,
                                        ' . (smc_session()['default_setting']['search_product_by_cat'] == 1 ? 'concat(cat.Cat_Name,": ")' : ' "" ') . ' as Cat_Name,
                                        ' . (smc_session()['default_setting']['show_product_brand_invoice'] == 1 ? 'brand.brand_name' : ' "" ') . ' as brand_name,
                                        concat_ws(" ",p.Product_Name' . (smc_session()['default_setting']['show_product_brand_invoice'] == 1 ? ',brand.brand_name' : '') . ') AS Name ,
                                        ' . (!is_null($depot_id) ? 'if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)' : 'p.Product_Quantity') . ' AS Quantity,
                                        p.Product_VAT AS VAT,def_uom.UOM_Name as default_uom_name,
                                        p.vat_percent,p.vat2_percent,
                                        p.is_tax,p.is_lot,p.is_serial,p.is_service,p.is_ticket,
                                        ' . ($cmd == 1 ? 'p.UOM_ID' : ($is_sales == 1 ? 'if(p.default_sales_uom=0,if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id),p.default_sales_uom)' : ($is_purchase == 1 ? 'if(p.default_purchase_uom=0,if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id),p.default_purchase_uom)' : 'if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)'))) . ' as UOM_ID,
                                        ' . ($cmd == 1 ? 'uom_from' : ' GROUP_CONCAT(uom_from separator "/")') . ' AS Product_UOM,
                                        p.Status_ID,p.default_sales_uom,p.default_purchase_uom,
                                        p.Product_Limit_Discount,p.is_expiry,p.force_change_price,p.duration_reservation,p.recipe_qty,
                                        p.product_second_code' . $code_columns . ',def_view_uom.UOM_Name as def_view_uom_name

                                    FROM
                                        tbl_stock_products p
                        ' . (smc_session()['default_setting']['search_product_by_cat'] == 1 ?
                        ' inner join tbl_product_cat cat on cat.Cat_ID = p.Category_ID ' : '') . '
                         ' . (smc_session()['default_setting']['show_product_brand_invoice'] == 1 ?
                        ' left join tbl_brand_products brand on brand.brand_id = p.brand_id ' : '') . '
                        inner JOIN uom_conversions u ON p.Product_ID = u.Product_ID 
                        inner join tbl_stock_uom def_uom on def_uom.UOM_ID = p.UOM_ID
                        inner join tbl_stock_uom def_view_uom on def_view_uom.UOM_ID = p.default_view_uom_id

                        ' . $dep_cond . ' ' . $person_code_cond . '
                         WHERE 1=1 ' . $condition . '
                        ' . ($cmd == 1 ? '' : ' GROUP BY u.Product_ID ') . '
                        LIMIT 60 ');
        //        $prod_indxs = array();
        $exp_prod_ids = '';
        while ($row = $this->db->assoc($query)) {
            $row['has_optional'] = 0;
            $current_cost = CommonBusiness::viewCurrentProductCost($row["ID"]);
            $row['uom_conv'] = self::get_uom_conv($row['ID'], $row['UOM_ID']);
            if (!empty($row['uom_conv']))
                $row['Quantity'] = $row['Quantity'] / $row['uom_conv'];
            else
                $row['Quantity'] = 0;
            if ($row['is_expiry'] == 1)
                $exp_prod_ids .= (empty($exp_prod_ids) ? '' : ',') . $row['ID'];
            $row['class_currency'] = $curr_id;
            $row['Price'] = self::get_product_price($row['ID'], $classID, $row['UOM_ID']);
            $row['disc'] = self::get_prod_disc_by_class($row['ID'], $classID, $row['UOM_ID']);
            $cost = self::get_product_price($row['ID'], $supp_class, $row['UOM_ID']);
            //            echo $supp_curr_id.'===';
            $cost_in_local = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($supp_curr_id, smc_session()['local_currency'], $cost);
            $row['supp_cost'] = !empty($supp_class) ? $cost_in_local : $current_cost;
            $row['supp_prod_disc'] = !empty($supp_class) ? Product::get_prod_disc_by_class($row['ID'], $supp_class, $row['UOM_ID']) : 0;
            $row['Currency_Symbol'] = $curr_symbol;
            if($row['is_rate'] == 1){
                $row['Price']= $this->change_product_rate($row['Price']);
            }

            if(!smc_session()['default_setting']['products_without_vat']){
                $row['ttc_price'] = $row['Price'];
                $row['total_tax'] = $row['is_tax'] ? $tax_amount : 0;    
            }
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                    $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                }else{
                    $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
    
                }
            }
            $row['Price'] = CommonFunctions::public_round_number($row['Price']);

            $row['LAST_COST'] = CommonBusiness::viewLastProductCost($row["ID"]) * $row['uom_conv'];
            $row['LAST_COST'] =  CommonFunctions::public_round_number($row['LAST_COST']);
            $row['current_cost'] = $current_cost;
            if (!is_null($customer_id) && $this->perm->hasPermission('view_sales_last_price')) {
                $row['last_price'] = CommonBusiness::viewLastProductCustomerClassPrice($row["ID"], $customer_id, $classID);
            } else {
                $row['last_price'] = 0;
            }


            $row['loc'] = '';
            if ($cmd != 1) {
                $pids[] = $row['ID'];
            }
            $data[$row['ID']] = $row;
        }
        if (!empty($exp_prod_ids) && !empty(smc_session()['default_setting']['activate_oldest_expiry_selected'])) {
            $exp_data = self::get_product_expiries($exp_prod_ids);
            foreach ($exp_data as $prod_id => $exp_row) {
                $data[$prod_id]['oldest_expiry'] = $exp_row;
            }
        }
        if (!empty($data)) {
            $query = $this->db->query('select count(*) as mycount,product_id 
                from tbl_product_options where product_id in (' . implode(',', array_keys($data)) . ') 
                group by product_id');
            while ($row = $this->db->assoc($query)) {
                $data[$row['product_id']]['has_optional'] = 1;
            }
        }
        if (!empty($pids) && !is_null($depot_id) && smc_session()['default_setting']['display_shelf_locations'] == 1) {
            $pids_arr = implode(',', $pids);
            $query_dep = $this->db->query('select GROUP_CONCAT(d.shelf_name separator ",") as loc,s.product_id
                from tbl_product_shelf s
                join tbl_shelfs_depot d on s.shelf_depot_id = d.shelf_depot_id 
                where s.product_id in (' . $pids_arr . ') and s.depot_id = "' . $depot_id . '" 
                    group by s.product_id');
            while ($row = $this->db->assoc($query_dep)) {
                $data[$row['product_id']]['loc'] = $row['loc'];
            }
        }

        if (!empty($pids) && $cmd != 1) {
            $pids_arr = implode(',', $pids);
            $query_barcode = $this->db->query('SELECT `Bar_Code`,Product_ID FROM `tbl_uom_conversions` WHERE `Product_ID` in (' . $pids_arr . ') and Is_default = 1');
            while ($brow = $this->db->assoc($query_barcode)) {
                $data[$brow['Product_ID']]['Bar_Code'] = $brow['Bar_Code'];
            }
        }

        return $data;
    }

    public function addPricingClass() {
        $this->db->prepare_Stmt('INSERT INTO tbl_pricing_class ( Class_Name ) VALUES ( ? )', [&$this->info['PricingClass']]);
        $error = $this->db->error();
        return $error;
    }

    public function getAllSettings($id = null) {
        $data = array();
        $condition = '';
        if (!is_null($id))
            $condition = ' AND ID = "' . $id . '"';
        $query = $this->db->query('SELECT *
                                        FROM
                                    tbl_settings
                                WHERE
                                    1=1
                                ' . $condition);
        while ($row = $this->db->assoc($query)) {
            if (smc_session()['default_setting']['activate_allergy_intolerance'] == 1 || (smc_session()['default_setting']['activate_allergy_intolerance'] == 0 && $row['ID'] != 12 && $row['ID'] != 13))
                $data[] = $row;
        }
        return $data;
    }

    public function getFirstSetting() {
        $data = array();
        $query = $this->db->query('SELECT *
                                        FROM
                                    tbl_settings
                               LIMIT 1
                                ');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getSettingDetail($table, $col, $colName) {
        $data = array();
        $query = $this->db->query('SELECT 
                                    ' . $col . ' AS ID,
                                    ' . $colName . ' AS Name
                                FROM
                                    ' . $table
        );
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function settingSearch($term = null, $page, $limit, $type) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $getsetting = $this->db->query('select * from tbl_settings where Name = "' . $type . '"');
        $row = $this->db->assoc($getsetting);
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' where ' . $row['Column_Name'] . ' LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }
        $query = $this->db->query('SELECT 
                                    ' . $row['Column_ID'] . ' AS id,
                                    ' . $row['Column_Name'] . ' AS text
                                FROM
                                    ' . $row['Table_Name'] . ' ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter
        );

        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function catSearch($term = null, $page, $limit, $ignore_cat_tree = null) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and Cat_Name LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }
        if (!empty($ignore_cat_tree)) {
            $child_arr = array();
            $this->get_cat_child($ignore_cat_tree, $child_arr);
            if (!empty($child_arr))
                $cond.=' and Cat_ID not in (' . implode(',', $child_arr) . ')';
        }

        $query = $this->db->prepare_Stmt('SELECT Cat_ID as id, Cat_Name as text 
            FROM tbl_product_cat where 1=1 ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function searchVoidReason($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and reason_title LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }
        if (!is_null($this->info['type'])) {
            $cond .= ' or reason_type ="' . $this->info['type'] . '"';
        }
        $query = $this->db->prepare_Stmt('SELECT reason_id as id, reason_title as text 
            FROM tbl_void_reason where 1=1 
            and reason_type = 0' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function getVoidInvoiceReason() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_void_reason where  reason_type = 0 or  reason_type = 2');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function pricingSearch($term = null, $page, $limit, $with_currency = false, $is_virtual = null, $type = null, $supp_id = null, $classes_ids = '') {
        //        echo $classes_ids.'===';die();
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and Class_Name LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }
        if (!is_null($is_virtual)) {
            $cond .= ' and is_virtual = "' . $is_virtual . '"';
        }
        if (!is_null($type)) {
            $cond .= ' and type = "' . $type . '"';
        }
        if (!is_null($supp_id)) {
            $cond .= ' and (supplier_id = "' . $supp_id . '" or isnull(supplier_id))';
        }
        if (!empty($classes_ids)) {
            $cond .= ' and Class_ID in (' . $classes_ids . ') ';
        }
        //        echo $classes_ids.'===';
        $query = $this->db->prepare_Stmt('SELECT Class_ID as id, ' . ($with_currency ? "concat(Class_Name, ' - ', Currency_Symbol)" : 'Class_Name') . ' as text,is_virtual FROM tbl_pricing_class 
                ' . ($with_currency ? ' inner join tbl_common_currency using (Currency_ID) ' : '') . ' where 1=1
            ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (!empty($this->info['zero_class'])) {
            $data['data'][] = ['id' => 0, 'text' => CommonLanguage::getMessage('zero_price')];
        }
        if (!empty($this->info['purchase'])) {
            $data['data'][] = ['id' => 0, 'text' => CommonLanguage::getMessage('purchase')];
        }
        if (!empty($this->info['is_last_cost'])) {
            $data['data'][] = ['id' => 0, 'text' => CommonLanguage::getMessage('last_cost')];
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function printTemplateSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and template_name LIKE ?';
            $data_filter[] = "%" . $term . "%";
        }
        $query = $this->db->prepare_Stmt('SELECT template_id as id,
                                          template_name as text
                                   FROM tbl_print_template  
                                   where template_key = "barcode"
            ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function productSearch($term = null, $page, $limit, $cat = 0) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $term = str_replace(" ", "%", trim($term));
            $cond .= ' and ( products.Product_Name LIKE ? or products.Product_Code LIKE ?  ' . (smc_session()['default_setting']['activate_search_product_second_code'] == 1 ? ' or products.product_second_code LIKE ? ' : '') . ')';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
            if (smc_session()['default_setting']['activate_search_product_second_code'] == 1)
                $data_filter[] = "%" . $term . "%";
        }
        if (!empty($cat)) {
            $cond .= ' and products.Category_ID = "' . $cat . '"';
        }
        if (!empty($this->info['Status_ID'])) {
            $cond .= ' and products.Status_ID = "1" ';
        }
        if (!empty($this->info['on_scale'])) {
            $cond .= ' and products.on_scale = "' . $this->info['on_scale'] . '" ';
        }
        if (!empty($this->info['is_not_service'])) {
            $cond .= ' and products.is_service <> 1 ';
        }
        if (!empty($this->info['is_edited'])) {
            $cond .= ' and (products.Status_ID = 1 or (products.Status_ID = 0 and products.Product_ID = "' . $this->info['is_edited'] . '") )';
        }
        $query = $this->db->prepare_Stmt('
        SELECT products.Product_ID as id,concat_ws (" - ",products.Product_Name,products.Product_Code' . (smc_session()['default_setting']['activate_search_product_second_code'] == 1 ? ',products.product_second_code' : '') . (!empty($this->info['show_default_uom']) ? ',uom.UOM_Name' : '') . ') as text,
        uom.UOM_ID,uom.UOM_Name,products.Product_Vat
            FROM tbl_stock_products products 
            inner join tbl_stock_uom uom using (UOM_ID) where 1=1 ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            if (!empty($this->info['ticketing_price'])) {
                $row['price'] = self::get_ticketing_price($row['id'], $row['UOM_ID'], $row['Product_Vat']);
            }
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function productBarCodeSearch() {
        $data = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($this->info['term'])) {
            $cond .= ' and (Bar_Code LIKE ? )';
            $data_filter[] = "%" . $this->info['term'] . "%";
        }
        $query = $this->db->prepare_Stmt('SELECT Bar_Code as id,
                                          Bar_Code as text
                                    FROM tbl_uom_conversions  where 1=1
                                    ' . $cond . ' limit 30', $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function recipeProductSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( Product_Name LIKE ? or Product_Code LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        $product_ids = array();
        $product_query = $this->db->query('select distinct(main_product_id) as product_id from tbl_products_link');
        while ($row1 = $this->db->assoc($product_query)) {
            $product_ids[] = $row1['product_id'];
        }
        $cond .=!empty($product_ids) ? ' and Product_ID in (' . implode(",", $product_ids) . ')' : ' and Product_ID isnull';
        $query = $this->db->prepare_Stmt('SELECT Product_ID as id,
                                          concat (Product_Name," - ",Product_Code) as text
                                    FROM  tbl_stock_products 
                                    where 1=1 ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function deleteSettingEntry($table, $col, $id) {
        if ($table == 'tbl_stock_uom') {
            $uom_query = $this->db->query('select * from tbl_uom_conversions where uom_from = "' . $id . '" or uom_to = "' . $id . '" limit 1');
            $uom_count = $this->db->rowsno($uom_query);
            if ($uom_count > 0) {
                return [CommonLanguage::getMessage('unable_delete_uom')];
            }
        } else if ($table == 'tbl_allergy' || $table == 'tbl_intolerance') {
            $col_name = $table == 'tbl_allergy' ? 'allergy_id' : 'intolerance_id';
            $cust_allergy_tolerance_query = $this->db->query("select * from tbl_customers where {$col_name} in ({$id})  limit 1");
            $cust_allergy_tolerance_count = $this->db->rowsno($cust_allergy_tolerance_query);
            if ($cust_allergy_tolerance_count > 0) {
                return [CommonLanguage::getMessage($table == 'tbl_allergy' ? 'unable_delete_allergy' : 'unable_delete_intolerance')];
            }
            $cust_pos_allergy_tolerance_query = $this->db->query("select * from tbl_pos_customers where {$col_name} in ({$id})  limit 1");
            $cust_pos_allergy_tolerance_count = $this->db->rowsno($cust_pos_allergy_tolerance_query);
            if ($cust_pos_allergy_tolerance_count > 0) {
                return [CommonLanguage::getMessage($table == 'tbl_allergy' ? 'unable_delete_allergy' : 'unable_delete_intolerance')];
            }
        } else if ($table == 'tbl_stock_categories') {
            $depot_cat_query = $this->db->query('select * from tbl_stock_depot_warehouse where Depot_Category_ID = "' . $id . '" limit 1');
            $depot_cat_count = $this->db->rowsno($depot_cat_query);
            if ($depot_cat_count > 0) {
                return [CommonLanguage::getMessage('unable_delete_depot_cat')];
            }
        } else if ($table == 'tbl_fuel_type' || $table == 'tbl_vehicle_usage_type' || $table == 'tbl_vehicle_model' || $table == 'tbl_vehicle_type' || $table == 'tbl_garage_vehicle_zone') {
            if ($table == 'tbl_fuel_type' || $table == 'tbl_vehicle_usage_type' || $table == 'tbl_vehicle_model') {
                $col_name = 'Vehicle_' . $col;
            } else {
                if ($table == 'tbl_vehicle_type') {
                    $col_name = 'Vehicle_Make_Name_ID';
                } else {
                    $col_name = 'zone_id';
                }
            }
            $vehicle_query = $this->db->query("select * from tbl_garage_vehicle where {$col_name} = '" . $id . "' limit 1");
            $vehicle_count = $this->db->rowsno($vehicle_query);
            if ($vehicle_count > 0) {
                return [CommonLanguage::getMessage('unable_delete_record')];
            }
        }
        $this->db->prepare_Stmt("DELETE FROM {$table} WHERE {$col} = ?", [&$id]);
        $error = $this->db->error();
        return $error;
    }

    public function editSettingEntry($table, $col, $id, $colName, $newVal) {
        //        if ($option == 10) {
        //            $this->db->prepare_Stmt("UPDATE {$table} SET {$colName} = ?,Currency_ID = ? WHERE {$col} = ?", [&$newVal, &$currency_id, &$id]);
        //        } else {
        $this->db->prepare_Stmt("UPDATE {$table} SET {$colName} = ? WHERE {$col} = ?", [&$newVal, &$id]);
        //        }

        $error = $this->db->error();
        return $error;
    }

    public function addSettingEntry($table, $colName, $newVal) {
        //        if ($option == 10) {
        //            $this->db->prepare_Stmt("INSERT INTO {$table} SET {$colName} = ?,Currency_ID = ?", [&$newVal, &$currency_id]);
        //        } else {
        $this->db->prepare_Stmt("INSERT INTO {$table} SET {$colName} = ?", [&$newVal]);
        //        }

        $error = $this->db->error();
        return $error;
    }

    public function mainItemsHistory($time = null) {
        $items = array();
        $max_profit = 0;
        $max_seller_quantity = 0;
        $max_seller_price = 0;
        $max_profit_item_id = null;
        $max_seller_quantity_id = null;
        $max_seller_price_id = null;
        $products_query = $this->db->query('SELECT 
                                           p. Product_ID AS ID,
                                           p.Product_Code AS Code,
                                           p.Product_Name AS Name,
                                           p.Product_Quantity AS Current_Quantity,
                                           u.Bar_Code
                                        FROM
                                            tbl_stock_products p
                                        left join
                                            tbl_uom_conversions u
                                        on
                                            p.Product_ID = u.Product_ID
                                        WHERE 
                                            p.Status_ID =1
                    ');
        while ($products_row = $this->db->assoc($products_query)) {
            $product_invoice = !is_null($time) ? self::viewSoldQuantityPerItem($products_row['ID'], 0, $time) : self::viewSoldQuantityPerItem($products_row['ID'], 0);
            $product_purchase = !is_null($time) ? self::viewPurchasedQuantityPerItem($products_row['ID'], 0, $time) : self::viewPurchasedQuantityPerItem($products_row['ID'], 0);
            $products_row['Sold_Quantity'] = $product_invoice[2];
            $products_row['Sold_Price'] = $product_invoice[3];
            $products_row['Purchased_Quantity'] = $product_purchase[2];
            $products_row['Purchased_Price'] = $product_purchase[3];
            $products_row['Profit_Item'] = $products_row['Sold_Price'] - $products_row['Purchased_Price'];
            if ($products_row['Profit_Item'] > $max_profit) {
                $max_profit = $products_row['Profit_Item'];
                $max_profit_item_id = $products_row['Name'];
            }
            if ($products_row['Sold_Quantity'] > $max_seller_quantity) {
                $max_seller_quantity = $products_row['Sold_Quantity'];
                $max_seller_quantity_id = $products_row['Name'];
            }
            if ($products_row['Sold_Price'] > $max_seller_price) {
                $max_seller_price = $products_row['Sold_Price'];
                $max_seller_price_id = $products_row['Name'];
            }
            $products_row['Category_Name'] = 'Final Product';
            $items[] = $products_row;
        }


        $items['Best_Profit_Price'] = $max_profit;
        $items['Best_Profit_Item'] = $max_profit_item_id;
        $items['Best_Seller_Quantity'] = $max_seller_quantity;
        $items['Best_Seller_Quantity_ID'] = $max_seller_quantity_id;
        $items['Best_Seller_Price'] = $max_seller_price;
        $items['Best_Seller_Price_ID'] = $max_seller_price_id;
        return $items;
    }

    public function mainItemsHistory1() {
        $items = array();
        $max_profit = 0;
        $max_seller_quantity = 0;
        $max_seller_price = 0;
        $max_profit_item_id = null;
        $max_seller_quantity_id = null;
        $max_seller_price_id = null;
        $products_query = $this->db->query('SELECT 
                                            Product_ID AS ID,
                                            Product_Code AS Code,
                                            Product_Name AS Name,
                                            Product_Quantity AS Current_Quantity
                                        FROM
                                            tbl_stock_products
                                        WHERE 
                                            Status_ID =1
                    ');
        while ($products_row = $this->db->assoc($products_query)) {
            $product_invoice = self::viewSoldQuantityPerItem($products_row['ID'], 0);
            $product_purchase = self::viewPurchasedQuantityPerItem($products_row['ID'], 0);
            $products_row['Sold_Quantity'] = $product_invoice[2];
            $products_row['Sold_Price'] = $product_invoice[3];
            $products_row['Purchased_Quantity'] = $product_purchase[2];
            $products_row['Purchased_Price'] = $product_purchase[3];
            $products_row['Profit_Item'] = $products_row['Sold_Price'] - $products_row['Purchased_Price'];
            if ($products_row['Profit_Item'] > $max_profit) {
                $max_profit = $products_row['Profit_Item'];
                $max_profit_item_id = $products_row['Name'];
            }
            if ($products_row['Sold_Quantity'] > $max_seller_quantity) {
                $max_seller_quantity = $products_row['Sold_Quantity'];
                $max_seller_quantity_id = $products_row['Name'];
            }
            if ($products_row['Sold_Price'] > $max_seller_price) {
                $max_seller_price = $products_row['Sold_Price'];
                $max_seller_price_id = $products_row['Name'];
            }
            $products_row['Category_Name'] = 'Final Product';
            $items[] = $products_row;
        }


        $items['Best_Profit_Price'] = $max_profit;
        $items['Best_Profit_Item'] = $max_profit_item_id;
        $items['Best_Seller_Quantity'] = $max_seller_quantity;
        $items['Best_Seller_Quantity_ID'] = $max_seller_quantity_id;
        $items['Best_Seller_Price'] = $max_seller_price;
        $items['Best_Seller_Price_ID'] = $max_seller_price_id;
        return $items;
    }

    private function viewSoldQuantityPerItem($id, $cat_id, $time = null) {
        $sold_quantity = 0;
        $sold_price = 0.0;
        $Best_Employee = '';
        $Best_Customer = '';
        if (!is_null($time)) {
            $current_time = $time;
        } else {
            $current_time = date("Y-m-d");
        }


        $sold_query = $this->db->query('SELECT 
                                            d.Product_Quantity,
                                            d.Product_Net_Price,
                                            i.Invoice_Currency,
                                            i.Logged_ID,
                                            i.Customer_ID
                                        FROM 
                                            tbl_invoice_products_details d
                                        LEFT JOIN 
                                            tbl_invoices i
                                        ON 
                                            i.Invoice_ID_Auto = d.Invoice_ID_Auto
                                        WHERE 
                                            d.Product_ID = "' . $id . '"
                                        and
                                            i.Invoice_Date >= "' . $current_time . '"
                    ');
        while ($sold_row = $this->db->assoc($sold_query)) {
            $Best_Employee = self::returnBestEmployeeSeller($sold_row['Logged_ID']);
            $Best_Customer = self::returnBestCustomerSeller($sold_row['Customer_ID']);
            $sold_quantity += $sold_row['Product_Quantity'];
            $sold_price += CurrencyFactory::returnPriceInDefaultCurrencyValue($sold_row['Invoice_Currency'], $sold_row['Product_Net_Price']);
        }
        $sold_price = CommonFunctions::public_round_number($sold_price);
        $data = array($Best_Employee ? $Best_Employee : "No Employee", $Best_Customer ? $Best_Customer : "not Sales", $sold_quantity, $sold_price);
        return $data;
    }

    private function viewPurchasedQuantityPerItem($id, $cat_id, $time = null) {
        $purchased_quantity = 0;
        $purchased_price = 0.0;
        $Best_Employee = '';
        $Best_Supplier = '';
        if (!is_null($time)) {
            $current_time = $time;
        } else {
            $current_time = date("Y-m-d");
        }
        $purchased_query = $this->db->query('SELECT 
                                            d.Item_Quantity,
                                            d.Product_Total_Price,
                                            i.Currency_ID,
                                            i.Logged_ID,
                                            i.Supplier_ID
                                        FROM 
                                            tbl_inventory_purchase_items d
                                        LEFT JOIN 
                                            tbl_inventory_purchases i
                                        ON 
                                            i.Purchase_ID_Auto = d.Purchase_ID_Auto
                                        WHERE 
                                            d.Product_ID = "' . $id . '"
                                         and
                                            i.Purchase_Date  >= "' . $current_time . '"
                    ');
        while ($purchased_row = $this->db->assoc($purchased_query)) {
            $Best_Employee = self::returnBestEmployeeSeller($purchased_row['Logged_ID']);
            $Best_Supplier = self::returnBestSupplierSeller($purchased_row['Supplier_ID']);
            $purchased_quantity += $purchased_row['Item_Quantity'];
            $purchased_price += CurrencyFactory::returnPriceInDefaultCurrencyValue($purchased_row['Currency_ID'], $purchased_row['Product_Total_Price']);
        }
        $purchased_price = CommonFunctions::public_round_number($purchased_price);
        $data = array($Best_Employee ? $Best_Employee : "No Employee", $Best_Supplier ? $Best_Supplier : "not Purchased", $purchased_quantity, $purchased_price);
        return $data;
    }

    private function getCatagoriesByParent($parent_id) {
        $data = array();
        $query = $this->db->query('SELECT 
                                        *
                                    FROM 
                                        tbl_product_cat
                                    WHERE 
                                        Parent_ID = "' . $parent_id . '"
									ORDER BY Cat_ID
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        return $data;
    }

    private function getProductsByCat($cat_id) {
        $data = array();
        $query = $this->db->query('SELECT 
                                        *
                                    FROM 
                                        tbl_stock_products
                                    WHERE 
                                        Category_ID = "' . $cat_id . '"
                                    AND 
                                        Status_ID = 1
									ORDER BY Product_ID
                ');
        while ($row = $this->db->assoc($query))
            $data[] = $row;
        return $data;
    }

    public function getProductsTree() {
        $result = array();
        $temp = array();
        $main_categories = self::getCatagoriesByParent(0);
        $k = 0;
        for ($i = 0; $i < count($main_categories); $i++) {
            $count_pr = 0;
            $sub_categories = self::getCatagoriesByParent($main_categories[$i]['Cat_ID']);
            if (count($sub_categories) > 0) {
                $l = 0;
                $temp = array();
                for ($j = 0; $j < count($sub_categories); $j++) {
                    $temp = self::getProductsByCat($sub_categories[$j]['Cat_ID']);
                    if (count($temp) > 0) {
                        $count_pr += count($temp);
                        $result[$k][$l] = $temp;
                        $result[$k][$l]['Sub_Cat_Name'] = $sub_categories[$j]['Cat_Name'];
                        $result[$k][$l]['Sub_Cat_ID'] = $sub_categories[$j]['Cat_ID'];
                        $l++;
                    }
                }
                if (count($temp) > 0) {
                    $result[$k]['Count_Product_Per_Main_Cat'] = $count_pr;
                    $result[$k]['Main_Cat_Name'] = $main_categories[$i]['Cat_Name'];
                    $result[$k]['Main_Cat_ID'] = $main_categories[$i]['Cat_ID'];
                    $k++;
                }
            }
        }
        return $result;
    }

    public function itemsHistoryDetails($product_ID) {
        $data = array();
        $query = $this->db->query(' SELECT 
                                            p.Product_ID,
                                            p.Product_Code,
                                            p.Product_Name,
                                            p.Product_Quantity,
                                            c.Cat_Name
                                    FROM 
                                             tbl_stock_products p 
                                    LEFT JOIN
                                         tbl_product_cat c
                                    ON 
                                            p.Category_ID = c.Cat_ID
                                    WHERE 
                                            p.Status_ID = 1
                                    AND 
                                            p.Product_ID = "' . $product_ID . '"
		');
        while ($products_row = $this->db->assoc($query)) {
            $product_invoice = self::viewSoldQuantityPerItem($products_row['Product_ID'], 0);
            $product_purchase = self::viewPurchasedQuantityPerItem($products_row['Product_ID'], 0);
            $products_row['Employee_Name'] = $product_invoice[0];
            $products_row['Customer_Name'] = $product_invoice[1];
            $products_row['Sold_Quantity'] = $product_invoice[2];
            $products_row['Sold_Price'] = $product_invoice[3];
            $products_row['Employee_Name_Purchase'] = $product_purchase[0];
            $products_row['Supplier_Name'] = $product_purchase[1];
            $products_row['Purchased_Quantity'] = $product_purchase[2];
            $products_row['Purchased_Price'] = $product_purchase[3];
            $products_row['Profit_Item'] = $products_row['Sold_Price'] - $products_row['Purchased_Price'];
            $products_row['Category_Name'] = 'Final Product';
            $data = $products_row;
        }
        return $data;
    }

    private function returnBestEmployeeSeller($id) {
        $query = $this->db->query(' SELECT 
                                            CONCAT(e.Employee_FirstName, " ", e.Employee_MiddleName, " ", e.Employee_LastName) AS Employee_Name
                                    FROM 
                                            tbl_hrm_employee e
                                    LEFT JOIN 
                                            tbl_common_users u
                                    ON 
                                            e.Employee_ID = u.Employee_ID 
                                    WHERE 
                                            u.User_ID = "' . $id . '"
                                    AND 
                                            u.Status_ID = 1
		');
        $row = $this->db->assoc($query);
        return $row['Employee_Name'];
    }

    private function returnBestCustomerSeller($id) {
        $query = $this->db->query(' SELECT 
                                            Customer_Name
                                    FROM 
                                            tbl_customers
                                    WHERE 
                                            Customer_ID = "' . $id . '"
                                    AND 
                                            Status_ID = 1
		');
        $row = $this->db->assoc($query);
        return $row['Customer_Name'];
    }

    private function returnBestSupplierSeller($id) {
        $query = $this->db->query(' SELECT 
                                            Supplier_Name
                                    FROM 
                                            tbl_stock_suppliers
                                    WHERE 
                                            Supplier_ID = "' . $id . '"
                                    AND 
                                            Status_ID = 1
		');
        $row = $this->db->assoc($query);
        return $row['Supplier_Name'];
    }

    public function getSalesInvoicePurchasedByItem($Product_ID) {
        $data = array();
        $query = $this->db->query('SELECT 
										DISTINCT i.Invoice_Date 
								   FROM
								   		tbl_invoice_products_details id
								   LEFT JOIN
								   		tbl_invoices i 
								   ON 
								   		i.Invoice_ID = id.Invoice_ID
								   WHERE
								   		id.Product_ID = "' . $Product_ID . '"				
								');
        while ($row = $this->db->assoc($query)) {
            $item = self::getSoldedQtyPriceByDateItem($row['Invoice_Date'], $Product_ID);
            if (count($item) > 0) {
                $data[] = array('Invoice_Date' => $row['Invoice_Date'],
                    'Sold_Quantity' => $item[0],
                    'Sold_Price' => $item[1],
                    'Invoice_ID' => $item[2],
                    'Customer_ID' => $item[3]
                );
            }
        }
        return $data;
    }

    public function getInvoicePurchasedByItem($Product_ID) {
        $data = array();
        $query1 = $this->db->query('SELECT 
										DISTINCT p.Purchase_Date 
								   FROM
								   		tbl_inventory_purchase_items ip
								   LEFT JOIN
								   		tbl_inventory_purchases p 
								   ON 
								   		p.Purchase_ID = ip.Purchase_ID
								   WHERE
								   		ip.Product_ID = "' . $Product_ID . '"	
								');
        while ($row = $this->db->assoc($query1)) {
            $item = self::getPurchaseddQtyPriceByDateItem($row['Purchase_Date'], $Product_ID);
            $data[] = array('Purchase_Date' => $row['Purchase_Date'],
                'Purchased_Quantity' => $item[0],
                'Purchased_Price' => $item[1],
                'Purchase_ID' => $item[2],
                'Supplier_ID' => $item[3]
            );
        }
        return $data;
    }

    private function getSoldedQtyPriceByDateItem($date, $product_id) {
        $data = array();
        $inovice_price = 0.0;
        $inovice_quantity = 0.0;
        $invoice_IDs = array();
        $Cuustomer_IDs = array();
        $query = $this->db->query('SELECT 
                                            id.Invoice_ID,
                                                id.Product_Quantity AS Quantity,
                                                id.Product_Total_Price  AS Price,
                                                i.Invoice_Currency,
                                                i.Customer_ID
                                   FROM
                                                tbl_invoice_products_details id
                                   LEFT JOIN
                                                tbl_invoices i 
                                   ON 
                                                i.Invoice_ID = id.Invoice_ID
                                   WHERE
                                                id.Product_ID = "' . $product_id . '"
                                        AND 
                                                i.Invoice_Date = "' . $date . '"
								');
        while ($row = $this->db->assoc($query)) {
            $invoice_IDs[] = $row['Invoice_ID'];
            $Cuustomer_IDs[] = $row['Customer_ID'];
            $inovice_quantity += $row['Quantity'];
            $inovice_price += CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Invoice_Currency'], $row['Price']);
            $inovice_price = CommonFunctions::public_round_number($inovice_price);
        }
        if (count($invoice_IDs) > 0) {
            $invoice_IDs_val = implode('-', $invoice_IDs);
            $Cuustomer_IDs_val = implode('-', $Cuustomer_IDs);
            $data = [$inovice_quantity, $inovice_price, $invoice_IDs_val, $Cuustomer_IDs_val];
        }
        return $data;
    }

    private function getPurchaseddQtyPriceByDateItem($date, $product_id) {
        $data = array();
        $purchase_price = 0.0;
        $purchase_quantity = 0.0;
        $purchase_IDs_val = '';
        $Supplier_IDs_val = '';
        $purchase_IDs = array();
        $Supplier_IDs = array();
        $query = $this->db->query('SELECT 
                                        ip.Purchase_ID,
                                            ip.Item_Quantity AS Quantity,
                                            ip.Product_Total_Price  AS Price,
                                            p.Currency_ID,
                                            p.Supplier_ID
                                FROM
                                            tbl_inventory_purchase_items ip
                               LEFT JOIN
                                            tbl_inventory_purchases p 
                               ON 
                                            p.Purchase_ID = ip.Purchase_ID
                               WHERE
                                            ip.Product_ID = "' . $product_id . '"
                                    AND 
                                            p.Purchase_Date = "' . $date . '"
								');
        while ($row = $this->db->assoc($query)) {
            $purchase_IDs[] = $row['Purchase_ID'];
            $Supplier_IDs[] = $row['Supplier_ID'];
            $purchase_quantity += $row['Quantity'];
            $purchase_price += CurrencyFactory::returnPriceInDefaultCurrencyValue($row['Currency_ID'], $row['Price']);
            $purchase_price = CommonFunctions::public_round_number($purchase_price);
        }
        $purchase_IDs_val = implode('-', $purchase_IDs);
        $Supplier_IDs_val = implode('-', $Supplier_IDs);
        $data = [$purchase_quantity, $purchase_price, $purchase_IDs_val, $Supplier_IDs_val];
        return $data;
    }

    public function getProductsForCustomerByClass($catID, $customer_id = null, $class_id = null, $type = null) {
        $condition = ' and p.Status_ID = 1 AND p.Category_ID = "' . $catID . '" ';
        //        if(!empty($catID)){
        //            $condition.=' AND p.Category_ID = "' . $catID . '" ';
        //        }
        $page_row_col_array = array();
        $data = array();
        $tmp_data = array();
        //        $class_id = smc_session()['pricing_class_id'];
        if ($customer_id != 0 && !is_null($customer_id) && $class_id == 0) {
            $query_cust = $this->db->query('select Class_ID from tbl_customers where Customer_ID = "' . $customer_id . '"');
            $class_id = $this->db->assoc($query_cust)['Class_ID'];
        }
        if (!is_null($type)) {
            $condition .= ' and p.Product_Type in(0,' . $type . ')';
        }
        $query_class = $this->db->query('select Currency_ID,is_ttc,tax_amount from tbl_pricing_class where Class_ID = "' . $class_id . '"');
        $class_row = $this->db->assoc($query_class);
        $class_cur_id = $class_row['Currency_ID'];
        $is_ttc = $class_row['is_ttc'];
        $tax_amount = $class_row['tax_amount'];
        if (smc_session()['default_setting']['show_products_from_all_branches'] == 0) {
            $depot_id = !empty(smc_session()['user_accounts']['depot_id']) ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'];
            $branch_id = CommonBusiness::getBranchByDepot($depot_id);
            $condition .= ' and (p.branch_id is null or concat_ws("", ",", p.branch_id, ",") LIKE  "%,' . $branch_id . ',%")';
        }

         if($this->perm->hasPermission('Branches')){
            $condition .=   '';
        }else{
            $condition .= ' and (p.multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR p.multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '")';
         }
       

        $last_price_arr = array();
        //        echo $customer_id.'==';
        if (!is_null($customer_id) && $this->perm->hasPermission('view_last_price_pos') && !empty($catID)) {
            $product_ids = array();
            $prod_query = $this->db->query('select distinct Product_ID 
                from tbl_stock_products p where 1=1 ' . $condition);
            while ($row = $this->db->assoc($prod_query)) {
                $product_ids[] = $row['Product_ID'];
            }
            $last_price_arr = CommonBusiness::viewLastProductCustomerClassPrice($product_ids, $customer_id, $class_id);
        }
        $prod_indxs = array();
        $query = $this->db->query('SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name,
                                        p.Product_Quantity AS Quantity,
                                        p.is_tax,p.is_lot,p.is_serial,
                                        p.product_color,
                                        p.row_number,
                                        p.column_number,
                                        p.page_number,
                                        p.Product_VAT AS VAT,
                                        p.vat_percent,p.vat2_percent,
                                        p.hide_pos1,
                                        if(p.default_sales_uom=0,p.UOM_ID,p.default_sales_uom) as UOM_ID,
                                        u.Bar_Code,
                                        p.Product_Limit_Discount,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                        p.is_expiry,p.force_change_price,
                                        p.Category_ID,p.duration_reservation,
                                        p.is_service,p.recipe_qty
                                    FROM
                                        tbl_stock_products p	

                                    LEFT JOIN
                                        uom_conversions u
                                    ON 
                                        u.Product_ID = p.Product_ID
                                    WHERE
                                        1=1 and hide_pos1 = 0 ' . $condition . '
                                    GROUP BY p.Product_ID
                                    order by p.product_order asc 
                                ');
        $max_page = 0;
        $max_no = 0;
        $i = 0;
        $max_row_number = smc_session()['default_setting']['default_pos_row'];
        $max_column_number = smc_session()['default_setting']['default_pos_column'];
        while ($row = $this->db->assoc($query)) {
            $row['is_pos_disabled'] = 0;
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0 && $row['Quantity'] <= 0) {
                $row['is_pos_disabled'] = 1;
            }
            $row['has_optional'] = 0;
            $prod_indxs[$row['ID']] = $i;
            $row['uom_conv'] = self::get_uom_conv($row["ID"], $row['UOM_ID']);
            $row['tax_amount'] = $row['is_tax'] == 1 ? $tax_amount : 0;
            $row['Currency_ID'] = $class_cur_id;
            $row['Price'] = self::get_product_price($row["ID"], $class_id, $row['UOM_ID']);
            $row['disc'] = self::get_prod_disc_by_class($row["ID"], $class_id, $row['UOM_ID']);
            if($row['is_rate'] == 1){
                $row['Price']= $this->change_product_rate($row['Price']);
            }
            $row['ttc_price'] = $row['Price'];
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                    $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                }else{
                    $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
    
                }
            }
            $cost = smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? CommonBusiness::viewCurrentProductCost($row['ID']) : CommonBusiness::viewLastProductCost($row['ID']);
            $row['last_cost'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $class_cur_id, $cost);
            if (array_key_exists($row['ID'], $last_price_arr)) {
                $last_price = $last_price_arr[$row['ID']];
                //                $last_price = CommonBusiness::viewLastProductCustomerClassPrice($row["ID"], $customer_id, $class_id);
                $row['last_price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $class_cur_id, $last_price);
            } else {
                $row['last_price'] = 0;
            }

            $row['product_view'] = 'Product';
            //
            if ($row['page_number'] > 0) {
                $max_page = max($row['page_number'], $max_page);
                $max_no = max(intval("{$row['page_number']}{$row['row_number']}{$row['column_number']}"), $max_no);
                $page_row_col_array[$row['page_number']][$row['row_number']][$row['column_number']] = $i;
            }
            $tmp_data[$i] = $row;
            $i++;
        }

        if (!empty($prod_indxs)) {
            $query = $this->db->query('select count(*) as mycount,product_id 
                from tbl_product_options where product_id in (' . implode(',', array_keys($prod_indxs)) . ') 
                group by product_id');
            while ($row = $this->db->assoc($query)) {
                $tmp_data[$prod_indxs[$row['product_id']]]['has_optional'] = 1;
                if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0) {
                    $tmp_data[$prod_indxs[$row['product_id']]]['is_pos_disabled'] = 0;
                }
            }
            //
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0) {
                $query = $this->db->query('select count(*) as mycount,main_product_id 
                from tbl_products_link where main_product_id in (' . implode(',', array_keys($prod_indxs)) . ') 
                group by main_product_id');
                while ($row = $this->db->assoc($query)) {
                    $tmp_data[$prod_indxs[$row['main_product_id']]]['is_pos_disabled'] = 0;
                }
            }
        }
        if (smc_session()['default_setting']['activate_skip'] == 1) {
            for ($page = 1; $page <= $max_page; $page++) {
                for ($row_nb = 1; $row_nb <= $max_row_number; $row_nb++) {
                    for ($column = 1; $column <= $max_column_number; $column++) {
                        if (isset($page_row_col_array[$page][$row_nb][$column])) {
                            $row = $tmp_data[$page_row_col_array[$page][$row_nb][$column]];
                            $data[] = $row;
                            unset($tmp_data[$page_row_col_array[$page][$row_nb][$column]]);
                        } else {
                            $row = array('product_view' => 'Skip');
                            $data[] = $row;
                        }
                        $crnt_no = intval("{$page}{$row_nb}{$column}");
                        if ($crnt_no >= $max_no) //so if arrive to last page, stop at last row/col. and not fill remain page with skip items
                            break 3;    //break the 3 for loops
                    }
                }
            }
            //foreach($tmp_data as $row)
            //    $data[] = $row;
        }
        if (empty($data))    //here will enter condition if activate skip is false or true but no products related to page/row/col
            $data = $tmp_data;
        //
        return $data;
    }

    public function closeStock($logged_id) {
        $is_actual = 0;
        $this->db->query('START TRANSACTION');
        $local_currency = CurrencyFactory::returnLocalCurrency();
        $local_symbol = CurrencyFactory::getLocalCurrencySymbol();
        $today = Date::getToday();
        $query = $this->db->query('SELECT * FROM tbl_stock_closing ORDER BY Closing_Stock_Date DESC LIMIT 1');
        $row = $this->db->assoc($query);
        $codes = ["371002", "6052", "371001", "6051"];
        $ids_arr = JV::getAccountIDsByCodes($codes);
        if (!empty($row)) {
            $opening_stock = $row['Closing_Stock_Amount'];
            $stock = self::viewStockValue($row['Closing_Stock_Date']);
            $curent_value = $stock['Stock_Value'] + $opening_stock;
            $ref = $row['Closing_Stock_ID'] + 1;
        } else {
            $select = $this->db->query('SELECT 
                                            * 
                                        FROM 
                                            tbl_accounting_transactions
                                        WHERE 
                                            Account_ID = "' . $ids_arr . '" and is_actual = "' . $is_actual . '"
                    ');
            $row_select = $this->db->assoc($select);
            $open_value = CurrencyFactory::returnExchangedValueByExchangedID($row_select['Exchange_Rate_ID'], $row_select['Transaction_Amount'], $row_select['Currency_ID']);
            $stock = self::viewStockValue();
            $curent_value = $stock['Stock_Value'] + $open_value;
            $ref = 1;
        }
        $data_main = [
            &$curent_value,
            &$local_currency,
            &$today,
            &$logged_id
        ];
        $this->db->prepare_Stmt("
                                INSERT
                                    INTO
                                        tbl_stock_closing
                                    (
                                        Closing_Stock_Amount,
                                        Currency_ID,
                                        Closing_Stock_Date,
                                        Logged_ID
                                    )
                                        VALUES
                                    (
                                        ?,?,?,?
                                    )
                ", $data_main);
        $cid = $this->db->id();
        $first_jv = JV::returnJV($is_actual);
        $desc1 = 'Closing of Stock for ' . $today . ' with ' . $local_symbol . ' ' . $curent_value;

        //        $ids_arr = JV::getAccountIDsByCodes($codes);
        $data_1 = array(
            "JV_ID" => $first_jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $ids_arr['371002'],
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $curent_value,
            "Transaction_Date" => $today,
            "Currency_ID" => $local_currency,
            "Logged_ID" => $logged_id,
            "Transaction_Description" => $desc1,
            "Current_Ex_Rate" => "0",
            "main_id" => $cid,
            "main_type" => "cls"
        );
        JV::addTransaction($data_1, $is_actual);
        $data_2 = array(
            "JV_ID" => $first_jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $ids_arr['6052'],
            "Transaction_Type" => "Credit",
            "Transaction_Amount" => $curent_value,
            "Transaction_Date" => $today,
            "Currency_ID" => $local_currency,
            "Logged_ID" => $logged_id,
            "Transaction_Description" => $desc1,
            "Current_Ex_Rate" => "0",
            "main_id" => $cid,
            "main_type" => "cls"
        );
        JV::addTransaction($data_2, $is_actual);
        $second_jv = JV::returnJV($is_actual);
        $desc2 = 'Opening of Stock for ' . $today . ' with ' . $local_symbol . ' ' . $curent_value;
        $data_3 = array(
            "JV_ID" => $second_jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $ids_arr['6052'],
            "Transaction_Type" => "Debit",
            "Transaction_Amount" => $curent_value,
            "Transaction_Date" => $today,
            "Currency_ID" => $local_currency,
            "Logged_ID" => $logged_id,
            "Transaction_Description" => $desc2,
            "Current_Ex_Rate" => "0",
            "main_id" => $cid,
            "main_type" => "cls"
        );
        JV::addTransaction($data_3, $is_actual);
        $data_4 = array(
            "JV_ID" => $second_jv,
            "Transaction_Reference" => $ref,
            "Transaction_Account" => $ids_arr['371001'],
            "Transaction_Type" => "Credit",
            "Transaction_Amount" => $curent_value,
            "Transaction_Date" => $today,
            "Currency_ID" => $local_currency,
            "Logged_ID" => $logged_id,
            "Transaction_Description" => $desc2,
            "Current_Ex_Rate" => "0",
            "main_id" => $cid,
            "main_type" => "cls"
        );
        JV::addTransaction($data_4, $is_actual);

        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    /**
     * @todo to be fixed based on change of costing
     */
    public function viewStockValue($from_date = null) {
        $stock_cost = 0.0;
        $method = $this->db->query('SELECT 
                                        d.Method_ID,
                                        m.Pricing_Method_Name
                                    FROM 
                                        tbl_stock_default_pricing_method d
                                    LEFT JOIN 
                                        tbl_stock_pricing_methods m
                                    ON 
                                        m.Pricing_Method_ID = d.Method_ID
                                    WHERE 
                                        d.Default_Method_ID = 1
                ');
        $method_row = $this->db->assoc($method);
        if ($method_row['Method_ID'] == 1 || $method_row['Method_ID'] == 2) {
            $condition = '';
            if (!is_null($from_date))
                $condition .= ' AND date(date_time) > "' . $from_date . '"';
            $query = $this->db->query('SELECT
                                            sum(Unit_Cost * (remaining_quantity)) AS Product_Cost
                                        FROM
                                            tbl_stock_products_costs

                    ' . $condition);
            $row = $this->db->assoc($query);
            $stock_cost = $row['Product_Cost'];
            //            while ($row = $this->db->assoc($query)) {
            //                $cost = CurrencyFactory::returnExchangedValueByExchangedID($row['Exchange_Rate_ID'], $row['Product_Cost'], $row['Currency_ID']);
            //                $stock_cost += $cost;
            //            }
        } else {
            $products = $this->db->query('SELECT Product_ID,Product_Quantity FROM tbl_stock_products WHERE Status_ID = 1 AND Product_Quantity > 0');
            while ($product_row = $this->db->assoc($products)) {
                $cost_array = CommonBusiness::viewCostByAverage($product_row['Product_ID']);
                $stock_cost += ($cost_array[$product_row['Product_ID']] * $product_row['Product_Quantity']);
            }
        }
        $result = array('Method_Name' => $method_row['Pricing_Method_Name'],
            'Stock_Value' => $stock_cost
        );
        return $result;
    }

    public function getPricingMethod() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_pricing_methods');

        while ($row = $this->db->assoc($query)) {

            $data[] = $row;
        }
        return $data;
    }

    public function getNamePricingMethod() {
        $query = $this->db->query('SELECT 
										pm.Pricing_Method_Name 
								   FROM 
										tbl_stock_default_pricing_method d
								 	LEFT JOIN 
								   		tbl_stock_pricing_methods pm 
									ON 
										d.Method_ID = pm.Pricing_Method_ID

										');

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

    public function createPricingMethod() {
        $this->db->prepare_Stmt('INSERT INTO tbl_stock_default_pricing_method ( Method_ID ) VALUES  ( ? )', [&$this->info['Method_ID']]);
        $error = $this->db->error();
        return $error;
    }

    public function getItemsCategoryByType($type_id) {
        $data = array();
        $query = $this->db->query('SELECT 
                                            Cat_ID AS ID,
                                            Cat_Name AS Name
                                        FROM 
                                            tbl_product_cat
                                    ');

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

    public function getItemsByCategoryAndType($cat_id, $type_id) {
        $data = array();

        $query = $this->db->query('SELECT * FROM tbl_stock_products WHERE Category_ID = "' . $cat_id . '"');

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

    public function mergeCategories() {
        $this->db->query('START TRANSACTION');
        foreach ($this->info['CatToMerge'] as $item) {
            $this->db->prepare_Stmt('UPDATE
                                                tbl_stock_products
                                            SET 
                                                Category_ID = ?
                                            WHERE 
                                                Category_ID = ?
                                            AND 
                                                Status_ID = 1


                                            ', [&$this->info['Category_ID'], &$item]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function addCategoryInMerge() {
        $this->db->prepare_Stmt('INSERT INTO 
                                            tbl_product_cat 
                                        (
                                            Cat_Name,
                                            Parent_ID
                                        )
                                        VALUES
                                        (?,"0")', [&$this->info['CategoryToAdd']]);
        $error = $this->db->error();
        if (empty($error)) {
            $last_inserted = $this->db->query('SELECT 
                                                        Cat_ID AS ID,
                                                        Cat_Name AS Name
                                                    FROM 
                                                        tbl_product_cat
                                                    ORDER BY ID
                                                    DESC LIMIT 1
                                                    ');
            $row = $this->db->assoc($last_inserted);
            return ['OK', $row];
        } else {
            return ['error', $error];
        }
    }

    /**
     * @todo to be fixed after change of costing and transactions
     */
    public function mergeItems() {
        $is_updated = false;
        $ids = implode(",", $this->info['ItemToMerge']);
        $query = $this->db->query('SELECT 
                                            SUM(Product_Quantity) AS Total_Quantity
                                        FROM 
                                            tbl_stock_products
                                        WHERE 
                                            Product_ID IN (' . $ids . ')
                                        AND 
                                            Status_ID = 1
                    ');
        $total_quantity = $this->db->assoc($query)['Total_Quantity'];
        $update = $this->db->query('UPDATE
                                            tbl_stock_products
                                        SET 
                                            Product_Quantity = 0
                                        WHERE 
                                            Product_ID IN (' . $ids . ')
                                        AND 
                                            Status_ID = 1
                    ');
        if ($update) {
            $update2 = $this->db->query('UPDATE
                                                tbl_stock_products
                                            SET 
                                                Product_Quantity = Product_Quantity + "' . $total_quantity . '"
                                            WHERE 
                                                Product_ID = "' . $this->info['Product_ID'] . '"
                                            AND 
                                                Status_ID = 1
                        ');
            if ($update2) {
                $location_same = $this->db->query('SELECT 
                                                            t.Product_Depot_ID, SUM(f.Product_Depot_Quantity) AS Total_Quantity
                                                        FROM 
                                                            tbl_stock_product_location t
                                                        JOIN 
                                                            tbl_stock_product_location f
                                                        ON 
                                                            t.Product_Depot_ID = f.Product_Depot_ID
                                                        WHERE 
                                                            t.Status_ID = 1
                                                        AND 
                                                            f.Status_ID = 1
                                                        AND 
                                                            t.Location_Product_ID = "' . $this->info['Product_ID'] . '"
                                                        AND 
                                                            f.Location_Product_ID IN (' . $ids . ')
                                                        GROUP BY 
                                                            t.Product_Depot_ID
                                    ');
                $j = 0;
                $i = 0;
                while ($row_location = $this->db->assoc($location_same)) {
                    $i++;
                    $update_same_location = $this->db->query('UPDATE 
                                                                        tbl_stock_product_location
                                                                    SET 
                                                                        Product_Depot_Quantity = Product_Depot_Quantity + "' . $row_location['Total_Quantity'] . '"
                                                                    WHERE
                                                                        Status_ID = 1
                                                                    AND 
                                                                        Location_Product_ID = "' . $this->info['Product_ID'] . '"
                                                                    AND 
                                                                        Product_Depot_ID = "' . $row_location['Product_Depot_ID'] . '"
                                                ');
                    if ($update_same_location) {
                        $update_same_loc_pro = $this->db->query('UPDATE 
                                                                        tbl_stock_product_location
                                                                    SET 
                                                                        Status_ID = 0
                                                                    WHERE
                                                                        Status_ID = 1
                                                                    AND 
                                                                        Location_Product_ID IN (' . $ids . ')
                                                                    AND 
                                                                        Product_Depot_ID = "' . $row_location['Product_Depot_ID'] . '"
                                                ');
                        if ($update_same_loc_pro)
                            $j++;
                    }
                }
                if ($i == $j) {
                    $distinct_loc_pro = $this->db->query('SELECT
                                                                DISTINCT Product_Depot_ID, SUM(Product_Depot_Quantity) AS Total_Quantity
                                                            FROM
                                                                tbl_stock_product_location
                                                            WHERE
                                                                Status_ID = 1
                                                            AND 
                                                                Location_Product_ID IN (' . $ids . ')
                                                            AND 
                                                                Product_Depot_ID NOT IN (
                                                                                            SELECT 
                                                                                                DISTINCT t.Product_Depot_ID
                                                                                            FROM 
                                                                                                tbl_stock_product_location t
                                                                                            JOIN 
                                                                                                tbl_stock_product_location f
                                                                                            ON 
                                                                                                t.Product_Depot_ID = f.Product_Depot_ID
                                                                                            WHERE 
                                                                                                t.Status_ID = 1
                                                                                            AND 
                                                                                                f.Status_ID = 1
                                                                                            AND 
                                                                                                t.Location_Product_ID = "' . $this->info['Product_ID'] . '"
                                                                                            AND 
                                                                                                f.Location_Product_ID IN (' . $ids . ')
                                                                                            GROUP BY 
                                                                                                t.Product_Depot_ID
                                                                                        )
                                                            GROUP BY 
                                                                Product_Depot_ID
                                        ');
                    $k = 0;
                    $l = 0;
                    while ($row_distinct = $this->db->assoc($distinct_loc_pro)) {
                        $k++;
                        $insert = $this->db->query('INSERT INTO
                                                            tbl_stock_product_location
                                                        SET
                                                            Location_Product_ID = "' . $this->info['Product_ID'] . '",
                                                            Product_Depot_ID = "' . $row_distinct['Product_Depot_ID'] . '",
                                                            Product_Depot_Quantity = "' . $row_distinct['Total_Quantity'] . '",
                                                            Status_ID = 1,
                                                            Logged_ID = "' . $this->info[0] . '"
                                    ');
                        if ($insert) {
                            $update_after_insert = $this->db->query('UPDATE 
                                                                            tbl_stock_product_location
                                                                        SET 
                                                                            Status_ID = 0
                                                                        WHERE
                                                                            Status_ID = 1
                                                                        AND 
                                                                            Location_Product_ID IN (' . $ids . ')
                                                                        AND 
                                                                            Product_Depot_ID = "' . $row_distinct['Product_Depot_ID'] . '"
                                                    ');
                            if ($update_after_insert)
                                $j++;
                        }
                    }
                    if ($l == $k) {
                        $update_transactions = $this->db->query('UPDATE 
                                                                        tbl_stock_product_transactions
                                                                    SET 
                                                                        Product_ID = "' . $this->info['Product_ID'] . '"
                                                                    WHERE
                                                                        Product_ID IN (' . $ids . ')
                                                                    AND 
                                                                        Category_ID = 0
                                                ');
                        if ($update_transactions) {
                            $method = $this->db->query('SELECT Method_ID FROM tbl_stock_default_pricing_method WHERE Default_Method_ID = 1');
                            $meth_id = $this->db->assoc($method)['Method_ID'];
                            if ($meth_id == 1 or $meth_id == 2) {
                                $update_costs = $this->db->query('UPDATE 
                                                                        tbl_stock_products_costs
                                                                    SET 
                                                                        Product_ID = "' . $this->info['Product_ID'] . '"
                                                                    WHERE
                                                                        Product_ID IN (' . $ids . ')
                                                                    AND 
                                                                        Category_ID = 0
                                                ');
                                if ($update_costs)
                                    return true;
                            }
                            else if ($meth_id == 3) {
                                $update_costs = $this->db->query('UPDATE 
                                                                        tbl_stock_cost_average
                                                                    SET 
                                                                        Product_ID = "' . $this->info['Product_ID'] . '"
                                                                    WHERE
                                                                        Product_ID IN (' . $ids . ')
                                                                    AND 
                                                                        Category_ID = 0
                                                ');
                                if ($update_costs)
                                    return true;
                            } else
                                return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    public function viewProductExpiryQuantity($product_id, $category_id, $depot_id) {
        $data = array();
        $query = $this->db->query('SELECT 
                                        DISTINCT Expiry_Date
                                    FROM 
                                        tbl_stock_product_transactions a
                                    WHERE 
                                        Product_ID = "' . $product_id . '"
                                    AND
                                        Category_ID = "' . $category_id . '"
                                    AND
                                        Depot_ID = "' . $depot_id . '"
                                    AND
                                        Operation_Type = "+"

                ');
        while ($row = $this->db->assoc($query)) {
            $result = 0;
            $add = $this->db->query('SELECT 
                                        SUM(Product_Quantity) AS Added_Quantity
                                    FROM 
                                        tbl_stock_product_transactions a
                                    WHERE 
                                        Product_ID = "' . $product_id . '"
                                    AND
                                        Category_ID = "' . $category_id . '"
                                    AND
                                        Depot_ID = "' . $depot_id . '"
                                    AND 
                                        Expiry_Date = "' . $row['Expiry_Date'] . '"
                                    AND
                                        Operation_Type = "+"
                    ');
            $added_quantity = $this->db->assoc($add)['Added_Quantity'];
            $sub = $this->db->query('SELECT 
                                        SUM(Product_Quantity) AS Subtracted_Quantity
                                    FROM 
                                        tbl_stock_product_transactions a
                                    WHERE 
                                        Product_ID = "' . $product_id . '"
                                    AND
                                        Category_ID = "' . $category_id . '"
                                    AND
                                        Depot_ID = "' . $depot_id . '"
                                    AND 
                                        Expiry_Date = "' . $row['Expiry_Date'] . '"
                                    AND
                                        Operation_Type = "-"
                    ');
            $subtracted_quantity = $this->db->assoc($sub)['Subtracted_Quantity'];
            if (!is_null($subtracted_quantity))
                $result = $added_quantity - $subtracted_quantity;
            else
                $result = $added_quantity;
            if ($result > 0)
                $data[] = array("Expiry_Date" => $row['Expiry_Date'],
                    "Quantity" => $result
                );
        }
        return $data;
    }

    public function addUOMConversions() {
        $this->db->query("START TRANSACTION");
        $product = $this->info['products'];
        $old = array();
        foreach ($this->info['Con'] as $items) {
            $code = '';
            if (!array_key_exists('code', $items) or empty($items['code'])) {
                $query = $this->db->query("SELECT Product_Code FROM tbl_stock_products WHERE Product_ID = '" . $product . "'");
                $code = $this->db->assoc($query)['Product_Code'];
            } else
                $code = $items['code'];
            $arr = [&$items['uom_from'],
                &$items['conversion_amount'],
                &$items['uom_to'],
                &$product,
                &$code
            ];
            //                echo $code."//";
            //                echo "<pre>";
            //                die(print_r($arr));
            $temp = $items['uom_from'] . $items['uom_to'];
            if (!in_array($temp, $old)) {
                $old[] = $items['uom_from'] . $items['uom_to'];
                $this->db->prepare_Stmt("INSERT INTO tbl_uom_conversions
                                                (
                                                    uom_from,
                                                    conversion_amount,
                                                    uom_to,
                                                    Product_ID,
                                                    Bar_Code,
                                                    is_default

                                                )
                                                    VALUES
                                                (
                                                ?,?,?,?,?, " . ($items['uom_from'] == $items['uom_to'] ? '1' : '0') . " )", $arr);

                if ($items['uom_from'] == $items['uom_to']) {
                    $upd_arr = [&$items['uom_from'], &$product];
                    $this->db->prepare_Stmt("UPDATE 
                                                    tbl_stock_products
                                                 SET
                                                    UOM_ID = ?
                                                 WHERE
                                                    Product_ID = ?", $upd_arr
                    );
                }
            }
        }
        $error = $this->db->error();
        if (empty($error))
            $this->db->query('COMMIT');
        else
            $this->db->query('ROLLBACK');
        return array_unique($error);
    }

    public static function getConvertedQuantity($from_uom, $quantity, $product_id) {
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query('SELECT conversion_amount FROM tbl_uom_conversions WHERE Product_ID = "' . smc_escape($product_id) . '" AND uom_from = "' . smc_escape($from_uom) . '"');
        $conversion = $db->assoc($query)['conversion_amount'];
        $final_quantity = $quantity * $conversion;

        return $final_quantity;
    }

    public static function getReversedQuantity($from_uom, $quantity, $product_id) {
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query('SELECT conversion_amount FROM tbl_uom_conversions WHERE Product_ID = "' . smc_escape($product_id) . '" AND uom_from = "' . smc_escape($from_uom) . '"');
        $conversion = $db->assoc($query)['conversion_amount'];
        $final_quantity = $quantity / $conversion;

        return $final_quantity;
    }

    public function getLastSalesBonOrder($id) {
        $Invoice = '';
        $query = $this->db->query('SELECT Bon_Number FROM tbl_invoices where Invoice_ID_Auto =' . $id);
        while ($row = $this->db->assoc($query)) {
            $Invoice = $row['Bon_Number'];
        }
        return $Invoice;
    }

    public function getConversionsByProduct($id) {
        $data = array();
        $query = $this->db->query('SELECT * FROM uom_conversions WHERE Product_ID = "' . smc_escape($id) . '" AND conversion_amount <> 1');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function editUOMConversions() {
        $this->db->query('START TRANSACTION');
        foreach ($this->info['conversions'] as $item) {
            $data = [&$item['conv_amount'], &$item['code'], &$item['uom_from'], &$item['uom_to'], &$this->info['pid']];
            $this->db->prepare_Stmt('UPDATE 
                                        tbl_uom_conversions
                                     SET 
                                        conversion_amount = ?,
                                        Bar_Code = ?
                                     WHERE 
                                        uom_from = ?
                                     AND 
                                        uom_to = ?
                                     AND 
                                        Product_ID = ?
                                    ', $data);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function getTagNames() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tag_names');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getAllTags() {
        $data = array();
        $query = $this->db->query('SELECT *,GROUP_CONCAT(CONCAT(Type_ID,"-",Type_Name) separator "/") AS ID_Name FROM tags_view GROUP BY Tag_ID ');
        while ($row = $this->db->assoc($query)) {
            $data['records'][] = $row;
        }
        $query_max = $this->db->query('SELECT COUNT(Tag_ID) AS count FROM tags_view GROUP BY Tag_ID ORDER BY count DESC LIMIT 1');
        $max = $this->db->assoc($query_max);
        $data['Max'] = $max['count'];
        return $data;
    }

    public function addPrinters() {
        $this->db->query('START TRANSACTION');
        $data = [&$this->info['printer_name']];
        $this->db->prepare_Stmt("INSERT INTO tbl_printers (printer_name) VALUES (?)", $data);
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query("COMMIT");
        } else {
            $this->db->query("ROLLBACK");
        }
        return array_unique($error);
    }

    public function assignProductsToPrinters() {
        $invoices = implode(",", $this->info['IDs']);
        $this->db->query('START TRANSACTION');
        $this->db->query("UPDATE tbl_stock_products SET printer_id = {$this->info["printer_id"]} WHERE Product_ID IN ({$invoices})");
        $error = $this->db->error();
        if (empty($error))
            $this->db->query('COMMIT');
        else
            $this->db->query('ROLLBACK');
        return array_unique($error);
    }

    public function getPricingClasses($id = null) {
        $cond = '';
        if (!is_null($id)) {
            $query_uom = $this->db->query('select uom_from from tbl_uom_conversions where Product_ID = "' . $id . '" and is_default = 1');
            $uom = $this->db->assoc($query_uom)['uom_from'];
            $cond .= ' and Product_ID = "' . $id . '" and pr.UOM_ID = "' . $uom . '"';
        }
        $data = array();
        $query = $this->db->query('SELECT Class_ID,Class_Name,c.Currency_ID,Currency_Symbol,Currency_Name,
            Product_Price FROM tbl_pricing_class pc JOIN tbl_item_price_by_classes pr USING(Class_ID) 
            JOIN tbl_common_currency c ON c.Currency_ID = pc.Currency_ID where type=0 ' . $cond . ' GROUP BY Class_ID');
        while ($row = $this->db->assoc($query)) {
            $data[$row['Class_ID']] = $row;
        }
        return $data;
    }

    public function getPricesClasses() {
        $data = array();
        $query = $this->db->query('SELECT Class_ID,Class_Name,Currency_ID,Currency_Symbol,Currency_Name FROM tbl_pricing_class  JOIN tbl_common_currency USING(Currency_ID) where is_virtual = 0 and type=0');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getAllUOM() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_uom');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getProductsForAutoComplete($term, $class_id = 0) {
        $data = array();
        $products_id = array();
        $flag = empty($class_id) ? true : false;
        $class_id = empty($class_id) ? smc_session()['default_setting']['pricing_class_id'] : $class_id;
        $data_filter = ["%" . $term . "%", "%" . $term . "%"];
        $query = $this->db->prepare_Stmt('SELECT
                                        p.Product_ID AS ID,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name,
                                        p.Product_Name AS Disc,
                                        p.UOM_ID,
                                        u.Bar_Code
                                    FROM
                                        tbl_stock_products p

                                    join tbl_uom_conversions u on u.Product_ID = p.Product_ID and u.uom_from = p.UOM_ID
                                    WHERE
                                        p.Status_ID = 1
                                    AND 
                                        (p.Product_Code LIKE ?  OR p.Product_Name LIKE ?)
                                        ' . (!empty($this->info['product_id']) ? ' and p.Product_ID in (' . $this->info['product_id'] . ')' : '') . '
                                    LIMIT 60
                                ', $data_filter);
        while ($row = $this->db->assoc($query)) {
            $row['Product_Price'] = $flag ? '0' : self::get_product_price($row['ID'], $class_id, $row['UOM_ID'], true);
            //           echo $row['Product_Price'].'==';
            $data[$row['ID']] = $row;
            $products_id [] = $row['ID'];
        }
        $ids = implode(',', $products_id);
        $product_uom = $this->db->query('SELECT * FROM tbl_uom_conversions WHERE Product_ID IN (' . $ids . ') ORDER BY Is_Default DESC');
        while ($row = $this->db->assoc($product_uom)) {
            $data[$row['Product_ID']]['uom'][$row['uom_from']] = $row['uom_from'];
        }
        //        $prices_query = $this->db->query('SELECT Product_ID,Class_ID,Class_Name,CONCAT(Product_Price," ",Currency_Symbol) AS Price 
        //            FROM tbl_pricing_class JOIN tbl_item_price_by_classes pc USING(Class_ID) JOIN tbl_common_currency c 
        //            ON c.Currency_ID = pc.Currency_ID WHERE Product_ID IN (' . $ids . ')');
        //        while ($row = $this->db->assoc($prices_query)) {
        //            $data[$row['Product_ID']]['prices'][] = $row;
        //        }
        return !empty($this->info['product_id']) ? array_values($data) : $data;
    }

    //    public function real_print($printer, $file_name, $repeat, $paper_size) {
    //        //    public function real_print($file_name) {
    //
    //        $file_path = SYSTEM_PATH . "{$file_name}.pdf";
    //        $printer_path = SYSTEM_PATH . "cmd\pdfprint.exe";
    //        //"C:\wamp\www\cmd\pdfprint.exe" -printer "Honeywell PC42t (203 dpi)" -copies 2 "C:\wamp\www\cmd\pdf-sample.pdf"
    //        $inv_cmd = "\"{$printer_path}\"  -printer \"{$printer}\" -paper \"{$paper_size}\" -copies {$repeat} \"{$file_path}\"";
    //
    //
    //
    //        echo $inv_cmd;
    //        exec($inv_cmd);
    //        unlink($file_path);
    //    }

    
    public function print_production_barcode() {
        $this->info['site_link'] = SITE_LINK;
        $template_name = 'production_barcode';
        if (!empty($this->info['template_id']))
            $template_name = CommonFunctions::SpecificAttribute('tbl_print_template', 'template_id', $this->info['template_id'], 'template_key');
        $barcode_arr = array();
         
         
 
         
         
        //for single barcode
        $this->info['barcode'] = Forms::generate_barcode($this->info['Code']);
        $this->info['barcode_image'] = SITE_LINK . '/common_controller/GenerateBarCodeImage?code=' . $this->info['Code'];
        $this->info['qrcode_image'] = SITE_LINK . '/common_controller/GenerateQRCode?code=' . $this->info['Code'];
          
        $template_row = Forms::build_print_template($template_name, $this->info, array('barcode' => $barcode_arr));
        $html = $template_row['html'];
        if (smc_session()['default_setting']['barcode_sumatra_print'] != 1) {
            echo $html; //on html template already add: <body onload="window.print()">
            exit;
        }
        $filename = Forms::html2pdf($html, ["width" => $this->info['paper_width'], "height" => $this->info['paper_height']]);
        //we must specify portrait in order for sumatr to print it correctly
        $barcode_printer = Forms::getKeyPrinterName('barcode');
        Forms::real_print($barcode_printer, $filename, ['is_cmd' => true, 'orientation' => 'p', /* 'paper_size' => $this->info['paper_size'], */ ]);
    }
    public function printBarCode() {
        $this->info['site_link'] = SITE_LINK;
        $template_name = 'barcode';
        if (!empty($this->info['template_id']))
            $template_name = CommonFunctions::SpecificAttribute('tbl_print_template', 'template_id', $this->info['template_id'], 'template_key');
        $barcode_arr = array();
        $bar_code = $this->info['bar_code'];
        $loop_repeat = 1;
        $template_repeat = $this->info['repeat'];
        if (isset($this->info['is_multi']) && $this->info['is_multi'] == 1) {
            $template_name = 'barcode_multi';   //we use anothrt template for multi barcodes draw
            $loop_repeat = $this->info['repeat'];
            $template_repeat = 1;
            $start = $this->info['start'];
            //fill empty barcodes div to skip to the start position ex: if start =3 we must skip 2 div's
            for ($i = 1; $i < $start; $i++)
                $barcode_arr[] = array('barcode' => '&nbsp;', 'product_code' => '&nbsp;', 'barcode_image' => '&nbsp;', 'qrcode_image' => '&nbsp;', 'Code' => '&nbsp;', 'Desc' => '&nbsp;', 'price' => '&nbsp;');
        }
        //        if (count($bar_code) > 1) {
        if (count($bar_code) > 1)
            $template_name = 'barcode_items';
        for ($i = 0; $i < count($bar_code); $i++) {
            $barcode = Forms::generate_barcode($bar_code[$i]['Code']);
            $barcode_image = SITE_LINK . '/common_controller/GenerateBarCodeImage?code=' . $bar_code[$i]['Code'];
            $qrcode = SITE_LINK . '/common_controller/GenerateQRCode?code=' . $bar_code[$i]['Code'];
            $price = $this->info['price'] == 0 ? 0 : self::getProductPriceByUOMClass($bar_code[$i]['Product_ID'], $bar_code[$i]['UOM_ID'], $this->info['price']);
            for ($j = 1; $j <= $loop_repeat; $j++) {
                $barcode_arr[] = ['Name' => $this->info['Name'], 'price' => $price,
                    'barcode' => $barcode, 'Code' => $bar_code[$i]['Code'],'barcode_code' => $bar_code[$i]['Code'],
                    'barcode_image' => $barcode_image, 'qrcode_image' => $qrcode,
                    'product_code' => $bar_code[$i]['product_code'], 'Desc' => $bar_code[$i]['Desc'], 'Desc' => $bar_code[$i]['Desc']];
            }
        }

        //        } else {
        //for single barcode
        $this->info['barcode'] = Forms::generate_barcode($this->info['Code']);
        $this->info['barcode_code'] = $this->info['Code'];
        $this->info['barcode_image'] = SITE_LINK . '/common_controller/GenerateBarCodeImage?code=' . $this->info['Code'];
        $this->info['qrcode_image'] = SITE_LINK . '/common_controller/GenerateQRCode?code=' . $this->info['Code'];
        $this->info['price'] = $this->info['price'] == 0 ? 0 : self::getProductPriceByUOMClass($this->info['Product_ID'], $this->info['UOM_ID'], $this->info['price']);
        //        }

        $template_row = Forms::build_print_template($template_name, $this->info, array('barcode' => $barcode_arr));
        $html = $template_row['html'];
        if (smc_session()['default_setting']['barcode_sumatra_print'] != 1) {
            echo $html; //on html template already add: <body onload="window.print()">
            exit;
        }
        $filename = Forms::html2pdf($html, ["width" => $this->info['paper_width'], "height" => $this->info['paper_height']]);
        //we must specify portrait in order for sumatr to print it correctly
        $barcode_printer = Forms::getKeyPrinterName('barcode');
        Forms::real_print($barcode_printer, $filename, ['is_cmd' => true, 'orientation' => 'p', /* 'paper_size' => $this->info['paper_size'], */ 'repeat' => $template_repeat]);
    }

    public function getProductPriceByUOMClass($product_id, $uom_id, $class_id) {
        $price = self::get_product_price($product_id, $class_id, $uom_id, true);
        //        $query = $this->db->query('select concat_ws(" ",price.Product_Price,currency.Currency_Symbol) as price_currency
        //            from tbl_item_price_by_classes price inner join tbl_common_currency currency using(Currency_ID) 
        //            where Product_ID ="' . $product_id . '" and UOM_ID ="' . $uom_id . '" and Class_ID ="' . $class_id . '"');
        //        $row = $this->db->assoc($query);
        return $price;
    }

    //    public function printBarCode() {
    //        //die (json_encode("<body onload='window.print()'><h4>{$org_details[0]['Organization_Name']}</h4><span>{$this->info['price']}</span></body>"));
    //
    //        $org = new Organization;
    //        $org_details = $org->getOrganizationAddress();
    //        $pdf = new TCPDF('L', "mm", PDF_PAGE_FORMAT, true, 'UTF-8', false);
    //        $pdf->SetPrintHeader(false);
    //        $pdf->SetPrintFooter(false);
    //        // set margins
    //        $pdf->SetMargins(0, 0, 0);
    //        $pdf->SetHeaderMargin(0);
    //        $pdf->SetFooterMargin(0);
    //        // set auto page breaks
    //        $pdf->SetAutoPageBreak(false, 0);
    //        $pdf->AddPage('L', array(58, 30));
    //        $pdf->SetFont('dejavusans', 'B', 14);
    //        // CODE 128 AUTO
    //
    //        $pdf->Cell(29, 0, $org_details[0]['Organization_Name'], 0, 0, 'L', false, '', 1);
    //        $pdf->SetFont('dejavusans', 'B', 12);
    //        $pdf->Cell(29, 0, $this->info['price'], 0, 1, 'R', false, '', 1);
    //        $pdf->Ln(2);
    //        // define barcode style
    //        $style = array(
    //            'position' => '',
    //            'align' => 'C',
    //            'stretch' => false,
    //            'fitwidth' => false,
    //            'cellfitalign' => 'C',
    //            'border' => false,
    //            'hpadding' => 0,
    //            'vpadding' => 0,
    //            'fgcolor' => array(0, 0, 0),
    //            'bgcolor' => false,
    //            'text' => true,
    //            'font' => 'dejavusans',
    //            'fontsize' => 8,
    //            'stretchtext' => 4
    //        );
    //
    //        $pdf->write1DBarcode($this->info['Code'], 'C128', '', '', '', 14, '', $style, 'N');
    //
    //        $pdf->SetFont('dejavusans', '', 10);
    //        //        $pdf->Cell(50, 0, 'PANT 65/50 GIRL B.B JNS A.S PANT 65/50 GIRL B.B JNS A.S', 0, 1, 'L', false, '', 1);
    //        // $pdf->MultiCell(58, 0, 'PANT 65/50 GIRL B.B JNS A.S PANT 65/50 GIRL B.B JNS A.S', 0, 'R', false, 1, '', '', true,1);
    //        $pdf->MultiCell(58, 10, $this->info['Desc'], 0, 'C', false, 1, '', '', true, 1, false, true, 10, 'T', true);
    //        //        $pdf->Cell(50, 0, $this->info['Desc'], 0, 1, 'L', false, '', 1);
    //        //Close and output PDF document
    //        $filename = 'Bar' . (time() + rand());
    //
    //        $pdf->IncludeJS("print();");
    //
    //        //header("Content-type: application/pdf");
    //        $pdf->Output(SYSTEM_PATH . $filename . '.pdf', 'I');
    //
    //
    //        /*     $printer_query = $this->db->query('SELECT printer_name FROM tbl_printers WHERE is_default=0');
    //          $printer = $this->db->assoc($printer_query);
    //          $printer_name = $printer['printer_name']; */
    //        //        $paper_size = $this->info['paper_size'];
    //        //        $repeat = $this->info['repeat'];
    //        //        Forms::real_print($printer_name, $filename, $repeat, $paper_size);
    ////        Forms::real_print($filename);
    //        // die (json_encode($filename.'.pdf'));
    //    }

    public function getPaperSize() {
        $data = array();
        $query = $this->db->query('select * from paper_size');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function uploadExcelSheet() {
        //when finish to download an error excel if there is
        if (!empty($_GET['action']) && $_GET['action'] == 'error_excel') {
            $csv_err_file = empty($_GET['path']) ? '' : $_GET['path'];
            if (!empty($csv_err_file) && file_exists($csv_err_file) && strtolower(pathinfo($csv_err_file, PATHINFO_EXTENSION)) == 'csv') {
                header('Content-Type: text/csv; charset=utf-8');
                header('Content-Description: File Transfer');
                header('Content-Disposition: attachment; filename="' . basename($csv_err_file) . '"');
                header('Expires: 0');
                header('Content-Length: ' . filesize($csv_err_file));
                readfile($csv_err_file);
                unlink($csv_err_file);
            }
            exit;
        }
        //
        $max_uom_no = 3;
        $max_price_class = 4;
        //
        require dirname(__FILE__) . '/../PHPExcel/PHPExcel/IOFactory.php';
        $Fileextension = $_FILES['Document_File_Name']['tmp_name'];
        $excel = PHPExcel_IOFactory::load($Fileextension);
        $writer = PHPExcel_IOFactory::createWriter($excel, 'CSV');
        $writer->setDelimiter(";");
        $writer->setEnclosure("");
        self::convertxlsxtoCSV($Fileextension, 'output.csv');
        //
        $today_date = date('Y-m-d');

        //fill needed data array like uom, category,..
        $uom_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_uom');
        while ($row = $this->db->assoc($query))
            $uom_arr[strtolower($row['UOM_Name'])] = $row['UOM_ID'];
        //
        $pro_cat_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_product_cat');
        while ($row = $this->db->assoc($query)) //here a problem will occur if there is 2 categories with the same name even different parent/leve!
            $pro_cat_arr[strtolower($row['Cat_Name'])] = $row['Cat_ID'];
        //
        $printer_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_printers');
        while ($row = $this->db->assoc($query))
            $printer_arr[strtolower($row['printer_title'])] = $row['printer_id'];
        //
        $branch_arr = array();
        $query = $this->db->query('SELECT * from tbl_organization_branches');
        while ($row = $this->db->assoc($query))
            $branch_arr[strtolower($row['branch_name'])] = $row['branch_id'];
        //
        $brand_arr = array();
        $query = $this->db->query('SELECT * from tbl_brand_products');
        while ($row = $this->db->assoc($query))
            $brand_arr[strtolower($row['brand_name'])] = $row['brand_id'];
        //

        $j = 1;
        $class_curr_arr = array();
        $class_price_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_pricing_class where type=0 order by Class_ID asc');
        while ($row = $this->db->assoc($query)) {
            $class_curr_arr[$row['Class_ID']] = $row['Currency_ID'];
            if ($j <= $max_price_class)
                $class_price_arr[$j] = $row['Class_ID'];
            $j++;
        }
        //product limit max. discount for new products
        $tmp_limit_disc = 0;
        if (!empty($_POST['max_discount_per']) && $_POST['max_discount_per'] > 0 && $_POST['max_discount_per'] <= 100)
            $tmp_limit_disc = floatval($_POST['max_discount_per']);    //we make floatval like if he put scientifica number ex: 1e2
            //
        $upload_qty_cost_only = false;
        if (!empty($_POST['upload_qty_cost_only']) && $_POST['upload_qty_cost_only'] == 1)
            $upload_qty_cost_only = true;
        //we don't create temporary table as we can't join it twice like t1,t2 but for physical table we can
        //for temporary it gave error "Can't reopen table".
        $table_name = "tmp_product_import_" . microtime(true) . str_shuffle(microtime(true));
        $create_table = "create table `{$table_name}` (
            tmp_excel_row_no int(11) not null UNIQUE,
            tmp_pro_code varchar(100) not null,
            tmp_pro_name varchar(255) not null,
            tmp_cat_id int(11) not null,
            tmp_vat_per double DEFAULT '0',
            tmp_printer_id varchar(100) not null,
            tmp_branch_id varchar(100) not null,
            tmp_brand_id varchar(100) not null,
            tmp_def_uom_pro_qty double DEFAULT '0',
            tmp_def_uom_pro_cost double DEFAULT '0', ";
        $insert_str = "insert into `{$table_name}` ( ";
        $insert_str .= " tmp_excel_row_no, tmp_pro_code, tmp_pro_name, tmp_cat_id, tmp_vat_per, tmp_printer_id,tmp_branch_id, tmp_brand_id, tmp_def_uom_pro_qty, tmp_def_uom_pro_cost,";
        for ($i = 1; $i <= $max_uom_no; $i++) {
            $create_table .= "
                tmp_uom_id_{$i} int(11) not null,
                tmp_uom_rate_{$i} double DEFAULT '0',
                tmp_uom_barcode_{$i} varchar(255) DEFAULT '' not null,
                tmp_uom_add_barcode_{$i} text not null, ";
            $insert_str .= " tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_barcode_{$i}, tmp_uom_add_barcode_{$i}, ";
            for ($j = 1; $j <= $max_price_class; $j++) {
                $create_table .= "
                    tmp_uom_price_{$i}_{$j} double DEFAULT '0', ";
                $insert_str .= " tmp_uom_price_{$i}_{$j}, ";
            }
        }
        $create_table .= "
                tmp_pro_exist_id int(11) NULL DEFAULT NULL,
                tmp_pro_insert_id int(11) NULL DEFAULT NULL,
                tmp_is_error tinyint(4) DEFAULT '0',
                tmp_error_text varchar(255) not null
            )
            ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
        $insert_str = rtrim($insert_str, ", ") . " ) ";   //remove from last space and commas
        $this->db->query($create_table);
        //we moved start transaction below create table since if above and get error will not rollback
        $this->db->query('START TRANSACTION');
        //
        if (($getfile = fopen('output.csv', "r"))) {
            fgetcsv($getfile, 1000, ",");   //escape first row/header
            $row_no = 1;
            while (($data = fgetcsv($getfile, 1000, ","))) {
                //trim the data
                array_walk_recursive($data, function(&$value, $index) {
                    $value = trim($value);
                });
                //inset the row to the temp table
                $data_arr = array();
                $data_arr[] = $row_no;    //excel row no.
                $col = 0;
                if (empty($this->info['auto_generate_code']))
                    $pro_code = $data[$col++];
                else {
                    if (empty($init_pro_code))
                        $init_pro_code = self::getMaxProductCode();
                    else
                        $init_pro_code++;
                    $pro_code = $init_pro_code;
                }
                $data_arr[] = $pro_code;    //product code
                $data_arr[] = $data[$col++];    //product name
                $prod_cat_name = strtolower($data[$col++]);   //here make strtolower to make sure of small/capital 
                $data_arr[] = (isset($pro_cat_arr[$prod_cat_name]) ? $pro_cat_arr[$prod_cat_name] : 0);    //category id
                $data_arr[] = $data[$col++];    //vat percent
                //
                $printer_title = trim(strtolower($data[$col++]));   //here make strtolower to make sure of small/capital 
                $printer_ids = '';
                if (!empty($printer_title)) {
                    if (isset($printer_arr[$printer_title]))
                        $printer_ids = $printer_arr[$printer_title];
                    elseif (strpos($printer_title, ',') !== false) {
                        $tmp_prdct_prntrs = explode(',', $printer_title);
                        foreach ($tmp_prdct_prntrs as $tmp_printer_title) {
                            $tmp_printer_title = trim($tmp_printer_title);
                            if (!empty($tmp_printer_title) && isset($printer_arr[$tmp_printer_title]))
                                $printer_ids .= (empty($printer_ids) ? '' : ',') . $printer_arr[$tmp_printer_title];
                        }
                    }
                }
                $data_arr[] = $printer_ids; //printer id
                //
                $branch_name = trim(strtolower($data[$col++]));   //here make strtolower to make sure of small/capital 
                $branch_ids = '';
                if (!empty($branch_name)) {
                    if (isset($branch_arr[$branch_name]))
                        $branch_ids = $branch_arr[$branch_name];
                    elseif (strpos($branch_name, ',') !== false) {
                        $tmp_prdct_branches = explode(',', $branch_name);
                        foreach ($tmp_prdct_branches as $tmp_branch_name) {
                            $tmp_branch_name = trim($tmp_branch_name);
                            if (!empty($tmp_branch_name) && isset($branch_arr[$tmp_branch_name]))
                                $branch_ids .= (empty($branch_ids) ? '' : ',') . $branch_arr[$tmp_branch_name];
                        }
                    }
                }
                $data_arr[] = $branch_ids; //branch id
                //

                $brand_name = strtolower($data[$col++]);   //here make strtolower to make sure of small/capital 
                $data_arr[] = (isset($brand_arr[$brand_name]) ? $brand_arr[$brand_name] : 0);    //brand id
                //
                $data_arr[] = $data[$col++];    //product default uom qty.
                $data_arr[] = $data[$col++];    //product default uom cost, needed when insert the qty if there is, inserted in the local currency
                for ($i = 1; $i <= $max_uom_no; $i++) {
                    //here we end 0 and -1 to distinguish between filled not exist uom [-1] and empty uom [0]
                    $uom_name = strtolower($data[$col++]);  //here make strtolower to make sure of small/capital 
                    $data_arr[] = (isset($uom_arr[$uom_name]) ? $uom_arr[$uom_name] : (empty($uom_name) ? 0 : -1));    //uom id
                    $data_arr[] = ($i == 1 ? 1 : $data[$col++]);    //rate
                    $barcode_val = $data[$col++];   //barcode
                    if ($i == 1 && empty($barcode_val)) //at default unit if no barcode we take the product code
                        $barcode_val = $pro_code;
                    $data_arr[] = $barcode_val;
                    $data_arr[] = trim(preg_replace('/\s+/', ',', $data[$col++]));    //add-barcode
                    for ($j = 1; $j <= $max_price_class; $j++)
                        $data_arr[] = $data[$col++];  //prices
                }

                //echo "<pre>" . print_r($data, true) . print_r($data_arr, true) . "<br/>=====" . $col;
                if ($row_no == 1)
                    $insert_str .= " values (" . substr(str_repeat(",?", count($data_arr)), 1) . ") ";
                $this->db->prepare_Stmt($insert_str, $data_arr);
                $row_no++;
            }
        }
        //check that required fields not empty
        $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'Product Code,  Name, Category are Required Fields!' where tmp_is_error <> '1' 
                            and (tmp_pro_code = '' " . ($upload_qty_cost_only ? "" : " || tmp_pro_name = '' || tmp_cat_id = 0 ") . " ) ");
        //check vat percentage between 0 & 100
        if (!$upload_qty_cost_only)
            $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'VAT Percentage must be between 0 & 100' where tmp_is_error <> '1' and (tmp_vat_per < 0 || tmp_vat_per >100) ");
        //for exist products fill the product id and error if the imported data with different default uom
        //now we depend on product code only not on code & name since in if want to change name [needed for beauty house]
        $this->db->query("update `{$table_name}` t
                    inner join tbl_stock_products p on tmp_pro_code = Product_Code /*and tmp_pro_name = Product_Name*/
                set tmp_pro_exist_id = Product_ID, tmp_is_error = if(UOM_ID = tmp_uom_id_1, 0, 1)
                , tmp_error_text = if(UOM_ID = tmp_uom_id_1, '', 'Product Exist with Different Default UOM!')
                    where tmp_is_error <> '1' ");
        //check default uom not empty, and other units are valid uom names with rates
        for ($i = 1; $i <= $max_uom_no; $i++) {
            if ($i == 1)
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'Default UOM Not Exist!' where tmp_is_error <> '1' and tmp_uom_id_{$i} <= 0 ");
            elseif (!$upload_qty_cost_only) {
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Not Exist!' where tmp_is_error <> '1' and tmp_uom_id_{$i} = -1 ");
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Rate Error!' where tmp_is_error <> '1' and tmp_uom_id_{$i} > 0 and tmp_uom_rate_{$i} <= 0 ");
            }
            if ($upload_qty_cost_only)
                continue;
            //check if barcode already exist in db., note we don't check exist product with same id and uom
            $this->db->query("update `{$table_name}` 
                inner join tbl_uom_conversions on tmp_uom_barcode_{$i} = Bar_Code
            set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Barcode Already Exist in DB.!' 
            where tmp_is_error <> '1' and tmp_uom_id_{$i} > 0 and tmp_uom_barcode_{$i} <> '' 
                and (isNULL(tmp_pro_exist_id) || Product_ID <> tmp_pro_exist_id || uom_from <> tmp_uom_id_{$i})");
            //check if barcode exist in same unit but for other product in excel, no need to check that t2 not error
            $this->db->query("update `{$table_name}` t1 
                inner join `{$table_name}` t2 on t1.tmp_uom_barcode_{$i} = t2.tmp_uom_barcode_{$i}
            set t1.tmp_is_error = 1, t1.tmp_error_text = concat('UOM {$i} Barcode Already Exist in Excel At Row ', t2.tmp_excel_row_no) 
            where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                and t1.tmp_uom_id_{$i} > 0 and t1.tmp_uom_barcode_{$i} <> '' and t2.tmp_uom_id_{$i} > 0 ");
            //check if barcode already exist in different unit in excel, no need to check that t2 not error
            for ($k = $i + 1; $k <= $max_uom_no; $k++) {
                $this->db->query("update `{$table_name}` t1 
                    inner join `{$table_name}` t2 on t1.tmp_uom_barcode_{$i} = t2.tmp_uom_barcode_{$k}
                set t1.tmp_is_error = 1, t1.tmp_error_text = concat('UOM {$i} Barcode Already Exist in Excel At Row [UOM {$k}]', t2.tmp_excel_row_no) 
                where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                    and t1.tmp_uom_id_{$i} > 0 and t1.tmp_uom_barcode_{$i} <> '' and t2.tmp_uom_id_{$k} > 0 ");
            }
        }
        //make sure that no duplication in the excel data, here no need to check if error in t2 even if there is error we can stop t1
        //and send error to t1 with duplication..
        $this->db->query("update `{$table_name}` t1
                    inner join `{$table_name}` t2 on t1.tmp_pro_code = t2.tmp_pro_code /*and t1.tmp_pro_name = t2.tmp_pro_name*/
                set t1.tmp_is_error = '1', t1.tmp_error_text = concat('Same Product Exist in Excel At Row: ', t2.tmp_excel_row_no)
                    /*, t2.tmp_is_error = '1', t2.tmp_error_text = concat('Same Product Exist in Excel At Row: ', t1.tmp_excel_row_no)*/
                where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                    /*and t2.tmp_is_error <> '1'*/ ");
        //insert the new products
        if (smc_session()['plu_as_code'] == 1)
            $plu_type_fld = "if(tmp_uom_barcode_1 <> '', tmp_uom_barcode_1, tmp_pro_code)";
        else {
            $plu_query = $this->db->query("select max(Product_PLU) as plu from tbl_stock_products");
            $plu_assoc = $this->db->assoc($plu_query);
            $plu_value = (count($plu_assoc) > 0 ? $plu_assoc['plu'] : 0);
            $plu_type_fld = "(@plu_last_val := IFNULL(@plu_last_val, '{$plu_value}') + 1)";
        }
        //below we insert qty as zero and not tmp_def_uom_pro_qty since in below assign we already update this table product qty.
        if (!$upload_qty_cost_only) {
            $this->db->query("INSERT INTO `tbl_stock_products` (`Product_Code`, `Product_Name`, `Category_ID`, `printer_id`,`branch_id`, `brand_id`, `Currency_ID`, `Product_Quantity`, `Product_Cost`
                            , `UOM_ID`, `default_view_uom_id`, `default_view_rate` , `Product_VAT`, `vat_percent`, `Product_Limit_Discount`, `Status_ID`, `Logged_ID`, `Product_PLU`, `PLU_Type`, `Product_Arabic_Name`)
                        SELECT tmp_pro_code, tmp_pro_name, tmp_cat_id, if(tmp_printer_id= '',null,tmp_printer_id), if(tmp_branch_id= '',null,tmp_branch_id), tmp_brand_id, '" . smc_session()['local_currency'] . "', 0, tmp_def_uom_pro_cost
                            , tmp_uom_id_1, tmp_uom_id_1, 1, if(tmp_vat_per > 0, 1, 0), tmp_vat_per, '{$tmp_limit_disc}', 1, '" . Session::getUserID() . "', {$plu_type_fld}, 'N', ''
                        from `{$table_name}` where tmp_is_error <> '1' and isNULL(tmp_pro_exist_id) ");
            //fill the new inserted products ids which is not error and not already exist before
            $this->db->query("update `{$table_name}` t
                        inner join tbl_stock_products p on tmp_pro_code = Product_Code and tmp_pro_name = Product_Name
                    set tmp_pro_insert_id = Product_ID where tmp_is_error <> '1' and isNULL(tmp_pro_exist_id) ");
            //insert to the uoms conversion the new units, and insert the new related prices
            for ($i = 1; $i <= $max_uom_no; $i++) {
                $new_pro_uom_cond = " tmp_is_error <> '1' and !isNULL(tmp_pro_insert_id) and tmp_uom_id_{$i} > 0 ";
                $this->db->query("INSERT INTO `tbl_uom_conversions` (`uom_from`, `conversion_amount`, `uom_to`, `Product_ID`
                            , `is_default`, `Bar_Code`, `additional_barcodes`)
                        SELECT tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_id_1, tmp_pro_insert_id
                            , " . ($i == 1 ? '1' : '0') . ", if(tmp_uom_barcode_{$i} <> '', tmp_uom_barcode_{$i}, null), tmp_uom_add_barcode_{$i}
                        from `{$table_name}` where {$new_pro_uom_cond} ");
                for ($j = 1; $j <= count($class_price_arr); $j++) {
                    $price_class_id = $class_price_arr[$j];
                    $price_curr_id = $class_curr_arr[$price_class_id];
                    $this->db->query("INSERT INTO `tbl_item_price_by_classes` (`Class_ID`, `Product_ID`, `UOM_ID`, `Product_Price`
                            , `Currency_ID`, `Pricing_Date`, `Status_ID`, `Logged_ID`)
                        SELECT {$price_class_id}, tmp_pro_insert_id, tmp_uom_id_{$i}, tmp_uom_price_{$i}_{$j}
                             , {$price_curr_id}, '{$today_date}', 1, '" . Session::getUserID() . "'
                        from `{$table_name}` where {$new_pro_uom_cond} ");
                }
            }
        }
        //insert to the location if there is quantities use the default uom, local currency, .. 
        //here to update the new inserted added products or even exist already inserted products
        $query = $this->db->query("select if(isNULL(tmp_pro_exist_id), tmp_pro_insert_id, tmp_pro_exist_id) as pro_id, tmp_uom_id_1 as uom_id, tmp_def_uom_pro_qty as qty, tmp_def_uom_pro_cost as cost
            from `{$table_name}` where tmp_is_error <> '1' and (!isNULL(tmp_pro_insert_id) || !isNULL(tmp_pro_exist_id)) and tmp_def_uom_pro_qty > 0 ");
        if ($this->db->rowsno($query)) {
            $qty_data_arr = array('Products' => array());
            while ($row = $this->db->assoc($query)) {
                $qty_data_arr['Products'][] = array('Product_ID' => $row['pro_id'], 'UOM_ID' => $row['uom_id'], 'Item_Quantity' => $row['qty']
                    , 'Depot_ID' => (smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'])
                    , 'Currency_ID' => smc_session()['local_currency'], 'Item_Cost' => $row['cost']);
            }
            $warehouseDepot = new WarehouseDepot;
            //we must stop start transaction, commit, rollback,..!! since we use internal methods like below in warehouose depot 
            //so if in that method we make rollback or commit we don't know since $this->db is static and it is the same instance
            //so now if there is error inside warehouseDepot class will continue but here below when check db. error it will rollbck
            $warehouseDepot->stop_transaction_start_end = true;
            $warehouseDepot->setData($qty_data_arr)->addProductLocation();
        }
        //now we must update the already exist products where we already make sure that it is the with the same default uom
        if (!$upload_qty_cost_only) {
            $exst_pro_cond = " tmp_is_error <> '1' and !isNULL(tmp_pro_exist_id) ";
            $this->db->query("update tbl_stock_products p
                        inner join `{$table_name}` t on p.Product_ID = t.tmp_pro_exist_id 
                    set `Product_Name` = tmp_pro_name, `Category_ID` = tmp_cat_id, `printer_id` = if(tmp_printer_id='',null,tmp_printer_id)
                        ,`branch_id`=if(tmp_branch_id='',null,tmp_branch_id), `brand_id` = tmp_brand_id, `Product_VAT` = if(tmp_vat_per > 0, 1, 0), `vat_percent` = tmp_vat_per
                    where {$exst_pro_cond} ");
            //insert the new uoms conversion or update exist for the already exist products, and insert/update the new related prices
            for ($i = 1; $i <= $max_uom_no; $i++) {
                $exst_pro_uom_cond = $exst_pro_cond . " and tmp_uom_id_{$i} > 0 ";
                //here duplication will occur only if same product/uom but will not occur on barcode since we make checking before on barcode duplication
                //if it is exist we can not change the conversion amount/rate or we must check if not used we can change it but if used can not change it.
                $this->db->query("INSERT INTO `tbl_uom_conversions` (`uom_from`, `conversion_amount`, `uom_to`, `Product_ID`
                        , `is_default`, `Bar_Code`, `additional_barcodes`)
                    SELECT tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_id_1, tmp_pro_exist_id
                        , " . ($i == 1 ? '1' : '0') . ", tmp_uom_barcode_{$i}, tmp_uom_add_barcode_{$i}
                    from `{$table_name}` where {$exst_pro_uom_cond} 
                        ON DUPLICATE KEY UPDATE `Bar_Code` = tmp_uom_barcode_{$i}, additional_barcodes = tmp_uom_add_barcode_{$i} ");
                //
                for ($j = 1; $j <= count($class_price_arr); $j++) {
                    $price_class_id = $class_price_arr[$j];
                    $price_curr_id = $class_curr_arr[$price_class_id];
                    $this->db->query("INSERT INTO `tbl_item_price_by_classes` (`Class_ID`, `Product_ID`, `UOM_ID`, `Product_Price`
                        , `Currency_ID`, `Pricing_Date`, `Status_ID`, `Logged_ID`)
                    SELECT {$price_class_id}, tmp_pro_exist_id, tmp_uom_id_{$i}, tmp_uom_price_{$i}_{$j}
                         , {$price_curr_id}, '{$today_date}', 1, '" . Session::getUserID() . "'
                    from `{$table_name}` where {$exst_pro_uom_cond} 
                        ON DUPLICATE KEY UPDATE `Product_Price` = tmp_uom_price_{$i}_{$j}, Currency_ID = {$price_curr_id} ");
                }
            }
        }      
        
        //
        //die(print_r($this->db->error(), true));
        $error = $this->db->error();
        $html = "";
        $is_error = '0';
        if (empty($error)) {
            $this->db->query('COMMIT');
            //create error csv if there is
            $query = $this->db->query("SELECT tmp_excel_row_no, tmp_pro_code, tmp_pro_name, tmp_error_text 
                                    FROM `{$table_name}`  where tmp_is_error = '1' order by tmp_excel_row_no asc");
            if ($this->db->rowsno($query)) {
                $import_error_csv_path = SYSTEM_PATH . 'import-product-error.csv';
                $output = fopen($import_error_csv_path, 'w');
                //output the column header
                fputcsv($output, array('Excel Row Number', 'Code', 'Name', 'Error'));
                while ($row = $this->db->assoc($query))
                    fputcsv($output, $row);
                fclose($output);
                $html = "<iframe src='" . SITE_LINK . "/StockAjax/importProducts/?action=error_excel&path=" . urlencode($import_error_csv_path) . "' style='display:none;width:0px;height:0px;' ></iframe>";
            }
        } else {
            $this->db->query('ROLLBACK');
            $is_error = '1';
            $html = array_unique($error);
        }
        $this->db->query("DROP TABLE IF EXISTS `{$table_name}`");
        //
        return array('is_error' => $is_error, 'html' => $html);
    }
/*
    public function uploadExcelSheet() {
        //when finish to download an error excel if there is
        if (!empty($_GET['action']) && $_GET['action'] == 'error_excel') {
            $csv_err_file = empty($_GET['path']) ? '' : $_GET['path'];
            if (!empty($csv_err_file) && file_exists($csv_err_file) && strtolower(pathinfo($csv_err_file, PATHINFO_EXTENSION)) == 'csv') {
                header('Content-Type: text/csv; charset=utf-8');
                header('Content-Description: File Transfer');
                header('Content-Disposition: attachment; filename="' . basename($csv_err_file) . '"');
                header('Expires: 0');
                header('Content-Length: ' . filesize($csv_err_file));
                readfile($csv_err_file);
                unlink($csv_err_file);
            }
            exit;
        }
        //
        $max_uom_no = 3;
        $max_price_class = 4;
        //
        require dirname(__FILE__) . '/../PHPExcel/PHPExcel/IOFactory.php';
        $Fileextension = $_FILES['Document_File_Name']['tmp_name'];
        $excel = PHPExcel_IOFactory::load($Fileextension);
        $writer = PHPExcel_IOFactory::createWriter($excel, 'CSV');
        $writer->setDelimiter(";");
        $writer->setEnclosure("");
        self::convertxlsxtoCSV($Fileextension, 'output.csv');
        //
        $today_date = date('Y-m-d');

        //fill needed data array like uom, category,..
        $uom_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_uom');
        while ($row = $this->db->assoc($query))
            $uom_arr[strtolower($row['UOM_Name'])] = $row['UOM_ID'];
        //
        $pro_cat_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_product_cat');
        while ($row = $this->db->assoc($query)) //here a problem will occur if there is 2 categories with the same name even different parent/leve!
            $pro_cat_arr[strtolower($row['Cat_Name'])] = $row['Cat_ID'];
        //
        $printer_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_printers');
        while ($row = $this->db->assoc($query))
            $printer_arr[strtolower($row['printer_title'])] = $row['printer_id'];
        //
        $branch_arr = array();
        $query = $this->db->query('SELECT * from tbl_organization_branches');
        while ($row = $this->db->assoc($query))
            $branch_arr[strtolower($row['branch_name'])] = $row['branch_id'];
        //
        $brand_arr = array();
        $query = $this->db->query('SELECT * from tbl_brand_products');
        while ($row = $this->db->assoc($query))
            $brand_arr[strtolower($row['brand_name'])] = $row['brand_id'];
        //
      /*  $multi_branch_arr = array();
        $query = $this->db->query('SELECT * from tbl_stock_products');
        while ($row = $this->db->assoc($query))
            $multi_branch_arr[strtolower($row['multi_branch_id'])] = $row['Product_ID'];
        //

        $j = 1;
        $class_curr_arr = array();
        $class_price_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_pricing_class where type=0 order by Class_ID asc');
        while ($row = $this->db->assoc($query)) {
            $class_curr_arr[$row['Class_ID']] = $row['Currency_ID'];
            if ($j <= $max_price_class)
                $class_price_arr[$j] = $row['Class_ID'];
            $j++;
        }
        //product limit max. discount for new products
        $tmp_limit_disc = 0;
        if (!empty($_POST['max_discount_per']) && $_POST['max_discount_per'] > 0 && $_POST['max_discount_per'] <= 100)
            $tmp_limit_disc = floatval($_POST['max_discount_per']);    //we make floatval like if he put scientifica number ex: 1e2
            //
        $upload_qty_cost_only = false;
        if (!empty($_POST['upload_qty_cost_only']) && $_POST['upload_qty_cost_only'] == 1)
            $upload_qty_cost_only = true;
        //we don't create temporary table as we can't join it twice like t1,t2 but for physical table we can
        //for temporary it gave error "Can't reopen table".
        $table_name = "tmp_product_import_" . microtime(true) . str_shuffle(microtime(true));
        $create_table = "create table `{$table_name}` (
            tmp_excel_row_no int(11) not null UNIQUE,
            tmp_pro_code varchar(100) not null,
            tmp_pro_name varchar(255) not null,
            tmp_cat_id int(11) not null,
            tmp_vat_per double DEFAULT '0',
            tmp_printer_id varchar(100) not null,
            tmp_branch_id varchar(100) not null,
            tmp_multi_branch_id varchar(100) not null,
            tmp_brand_id varchar(100) not null,
            tmp_def_uom_pro_qty double DEFAULT '0',
            tmp_def_uom_pro_cost double DEFAULT '0', ";
        $insert_str = "insert into `{$table_name}` ( ";
        $insert_str .= " tmp_excel_row_no, tmp_pro_code, tmp_pro_name, tmp_cat_id, tmp_vat_per, tmp_printer_id,tmp_branch_id, tmp_multi_branch_id, tmp_brand_id, tmp_def_uom_pro_qty, tmp_def_uom_pro_cost,";
        for ($i = 1; $i <= $max_uom_no; $i++) {
            $create_table .= "
                tmp_uom_id_{$i} int(11) not null,
                tmp_uom_rate_{$i} double DEFAULT '0',
                tmp_uom_barcode_{$i} varchar(255) DEFAULT '' not null,
                tmp_uom_add_barcode_{$i} text not null, ";
            $insert_str .= " tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_barcode_{$i}, tmp_uom_add_barcode_{$i}, ";
            for ($j = 1; $j <= $max_price_class; $j++) {
                $create_table .= "
                    tmp_uom_price_{$i}_{$j} double DEFAULT '0', ";
                $insert_str .= " tmp_uom_price_{$i}_{$j}, ";
            }
        }
        $create_table .= "
                tmp_pro_exist_id int(11) NULL DEFAULT NULL,
                tmp_pro_insert_id int(11) NULL DEFAULT NULL,
                tmp_is_error tinyint(4) DEFAULT '0',
                tmp_error_text varchar(255) not null
            )
            ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
        $insert_str = rtrim($insert_str, ", ") . " ) ";   //remove from last space and commas
        $this->db->query($create_table);
        //we moved start transaction below create table since if above and get error will not rollback
        $this->db->query('START TRANSACTION');
        //
        if (($getfile = fopen('output.csv', "r"))) {
            fgetcsv($getfile, 1000, ",");   //escape first row/header
            $row_no = 1;
            while (($data = fgetcsv($getfile, 1000, ","))) {
                //trim the data
                array_walk_recursive($data, function(&$value, $index) {
                    $value = trim($value);
                });
                //inset the row to the temp table
                $data_arr = array();
                $data_arr[] = $row_no;    //excel row no.
                $col = 0;
                if (empty($this->info['auto_generate_code']))
                    $pro_code = $data[$col++];
                else {
                    if (empty($init_pro_code))
                        $init_pro_code = self::getMaxProductCode();
                    else
                        $init_pro_code++;
                    $pro_code = $init_pro_code;
                }
                $data_arr[] = $pro_code;    //product code
                $data_arr[] = $data[$col++];    //product name
                $prod_cat_name = strtolower($data[$col++]);   //here make strtolower to make sure of small/capital 
                $data_arr[] = (isset($pro_cat_arr[$prod_cat_name]) ? $pro_cat_arr[$prod_cat_name] : 0);    //category id
                $data_arr[] = $data[$col++];    //vat percent
                //
                $printer_title = trim(strtolower($data[$col++]));   //here make strtolower to make sure of small/capital 
                $printer_ids = '';
                if (!empty($printer_title)) {
                    if (isset($printer_arr[$printer_title]))
                        $printer_ids = $printer_arr[$printer_title];
                    elseif (strpos($printer_title, ',') !== false) {
                        $tmp_prdct_prntrs = explode(',', $printer_title);
                        foreach ($tmp_prdct_prntrs as $tmp_printer_title) {
                            $tmp_printer_title = trim($tmp_printer_title);
                            if (!empty($tmp_printer_title) && isset($printer_arr[$tmp_printer_title]))
                                $printer_ids .= (empty($printer_ids) ? '' : ',') . $printer_arr[$tmp_printer_title];
                        }
                    }
                }
                $data_arr[] = $printer_ids; //printer id
                //
                $branch_name = trim(strtolower($data[$col++]));   //here make strtolower to make sure of small/capital 
                $branch_ids = '';
                if (!empty($branch_name)) {
                    if (isset($branch_arr[$branch_name]))
                        $branch_ids = $branch_arr[$branch_name];
                    elseif (strpos($branch_name, ',') !== false) {
                        $tmp_prdct_branches = explode(',', $branch_name);
                        foreach ($tmp_prdct_branches as $tmp_branch_name) {
                            $tmp_branch_name = trim($tmp_branch_name);
                            if (!empty($tmp_branch_name) && isset($branch_arr[$tmp_branch_name]))
                                $branch_ids .= (empty($branch_ids) ? '' : ',') . $branch_arr[$tmp_branch_name];
                        }
                    }
                }
                $data_arr[] = $branch_ids; //branch id
                //

                $multi_branch_name = trim(strtolower($data[$col++]));   //here make strtolower to make sure of small/capital 
                $multi_branch_ids = '';
                if (!empty($multi_branch_name)) {
                    if (isset($multi_branch_arr[$multi_branch_name]))
                    $multi_branch_ids = $multi_branch_arr[$multi_branch_name];
                    elseif (strpos($multi_branch_name, ',') !== false) {
                        $tmp_prdct_multi_branches = explode(',', $multi_branch_name);
                        foreach ($tmp_prdct_multi_branches as $tmp_multi_branch_name) {
                            $tmp_multi_branch_name = trim($tmp_multi_branch_name);
                            if (!empty($tmp_multi_branch_name) && isset($multi_branch_arr[$tmp_multi_branch_name]))
                            $multi_branch_ids .= (empty($multi_branch_ids) ? '' : ',') . $multi_branch_arr[$tmp_multi_branch_name];
                        }
                    }
                }
                $data_arr[] = $multi_branch_ids; //multi branch id
                //
                $brand_name = strtolower($data[$col++]);   //here make strtolower to make sure of small/capital 
                $data_arr[] = (isset($brand_arr[$brand_name]) ? $brand_arr[$brand_name] : 0);    //brand id
                //
                $data_arr[] = $data[$col++];    //product default uom qty.
                $data_arr[] = $data[$col++];    //product default uom cost, needed when insert the qty if there is, inserted in the local currency
                for ($i = 1; $i <= $max_uom_no; $i++) {
                    //here we end 0 and -1 to distinguish between filled not exist uom [-1] and empty uom [0]
                    $uom_name = strtolower($data[$col++]);  //here make strtolower to make sure of small/capital 
                    $data_arr[] = (isset($uom_arr[$uom_name]) ? $uom_arr[$uom_name] : (empty($uom_name) ? 0 : -1));    //uom id
                    $data_arr[] = ($i == 1 ? 1 : $data[$col++]);    //rate
                    $barcode_val = $data[$col++];   //barcode
                    if ($i == 1 && empty($barcode_val)) //at default unit if no barcode we take the product code
                        $barcode_val = $pro_code;
                    $data_arr[] = $barcode_val;
                    $data_arr[] = trim(preg_replace('/\s+/', ',', $data[$col++]));    //add-barcode
                    for ($j = 1; $j <= $max_price_class; $j++)
                        $data_arr[] = $data[$col++];  //prices
                }

                //echo "<pre>" . print_r($data, true) . print_r($data_arr, true) . "<br/>=====" . $col;
                if ($row_no == 1)
                    $insert_str .= " values (" . substr(str_repeat(",?", count($data_arr)), 1) . ") ";
                $this->db->prepare_Stmt($insert_str, $data_arr);
                $row_no++;
            }
        }
        //check that required fields not empty
        $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'Product Code,  Name, Category are Required Fields!' where tmp_is_error <> '1' 
                            and (tmp_pro_code = '' " . ($upload_qty_cost_only ? "" : " || tmp_pro_name = '' || tmp_cat_id = 0 ") . " ) ");
        //check vat percentage between 0 & 100
        if (!$upload_qty_cost_only)
            $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'VAT Percentage must be between 0 & 100' where tmp_is_error <> '1' and (tmp_vat_per < 0 || tmp_vat_per >100) ");
        //for exist products fill the product id and error if the imported data with different default uom
        //now we depend on product code only not on code & name since in if want to change name [needed for beauty house]
        $this->db->query("update `{$table_name}` t
                    inner join tbl_stock_products p on tmp_pro_code = Product_Code /*and tmp_pro_name = Product_Name///////
                set tmp_pro_exist_id = Product_ID, tmp_is_error = if(UOM_ID = tmp_uom_id_1, 0, 1)
                , tmp_error_text = if(UOM_ID = tmp_uom_id_1, '', 'Product Exist with Different Default UOM!')
                    where tmp_is_error <> '1' ");
        //check default uom not empty, and other units are valid uom names with rates
        for ($i = 1; $i <= $max_uom_no; $i++) {
            if ($i == 1)
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'Default UOM Not Exist!' where tmp_is_error <> '1' and tmp_uom_id_{$i} <= 0 ");
            elseif (!$upload_qty_cost_only) {
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Not Exist!' where tmp_is_error <> '1' and tmp_uom_id_{$i} = -1 ");
                $this->db->query("update `{$table_name}` set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Rate Error!' where tmp_is_error <> '1' and tmp_uom_id_{$i} > 0 and tmp_uom_rate_{$i} <= 0 ");
            }
            if ($upload_qty_cost_only)
                continue;
            //check if barcode already exist in db., note we don't check exist product with same id and uom
            $this->db->query("update `{$table_name}` 
                inner join tbl_uom_conversions on tmp_uom_barcode_{$i} = Bar_Code
            set tmp_is_error = 1, tmp_error_text = 'UOM {$i} Barcode Already Exist in DB.!' 
            where tmp_is_error <> '1' and tmp_uom_id_{$i} > 0 and tmp_uom_barcode_{$i} <> '' 
                and (isNULL(tmp_pro_exist_id) || Product_ID <> tmp_pro_exist_id || uom_from <> tmp_uom_id_{$i})");
            //check if barcode exist in same unit but for other product in excel, no need to check that t2 not error
            $this->db->query("update `{$table_name}` t1 
                inner join `{$table_name}` t2 on t1.tmp_uom_barcode_{$i} = t2.tmp_uom_barcode_{$i}
            set t1.tmp_is_error = 1, t1.tmp_error_text = concat('UOM {$i} Barcode Already Exist in Excel At Row ', t2.tmp_excel_row_no) 
            where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                and t1.tmp_uom_id_{$i} > 0 and t1.tmp_uom_barcode_{$i} <> '' and t2.tmp_uom_id_{$i} > 0 ");
            //check if barcode already exist in different unit in excel, no need to check that t2 not error
            for ($k = $i + 1; $k <= $max_uom_no; $k++) {
                $this->db->query("update `{$table_name}` t1 
                    inner join `{$table_name}` t2 on t1.tmp_uom_barcode_{$i} = t2.tmp_uom_barcode_{$k}
                set t1.tmp_is_error = 1, t1.tmp_error_text = concat('UOM {$i} Barcode Already Exist in Excel At Row [UOM {$k}]', t2.tmp_excel_row_no) 
                where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                    and t1.tmp_uom_id_{$i} > 0 and t1.tmp_uom_barcode_{$i} <> '' and t2.tmp_uom_id_{$k} > 0 ");
            }
        }
        //make sure that no duplication in the excel data, here no need to check if error in t2 even if there is error we can stop t1
        //and send error to t1 with duplication..
        $this->db->query("update `{$table_name}` t1
                    inner join `{$table_name}` t2 on t1.tmp_pro_code = t2.tmp_pro_code /*and t1.tmp_pro_name = t2.tmp_pro_name///////////
                set t1.tmp_is_error = '1', t1.tmp_error_text = concat('Same Product Exist in Excel At Row: ', t2.tmp_excel_row_no)
                    /*, t2.tmp_is_error = '1', t2.tmp_error_text = concat('Same Product Exist in Excel At Row: ', t1.tmp_excel_row_no)/////////////
                where t1.tmp_excel_row_no <> t2.tmp_excel_row_no and t1.tmp_is_error <> '1' 
                    /*and t2.tmp_is_error <> '1'/////////// ");
        //insert the new products
        if (smc_session()['plu_as_code'] == 1)
            $plu_type_fld = "if(tmp_uom_barcode_1 <> '', tmp_uom_barcode_1, tmp_pro_code)";
        else {
            $plu_query = $this->db->query("select max(Product_PLU) as plu from tbl_stock_products");
            $plu_assoc = $this->db->assoc($plu_query);
            $plu_value = (count($plu_assoc) > 0 ? $plu_assoc['plu'] : 0);
            $plu_type_fld = "(@plu_last_val := IFNULL(@plu_last_val, '{$plu_value}') + 1)";
        }
        //below we insert qty as zero and not tmp_def_uom_pro_qty since in below assign we already update this table product qty.
        if (!$upload_qty_cost_only) {
            $this->db->query("INSERT INTO `tbl_stock_products` (`Product_Code`, `Product_Name`, `Category_ID`, `printer_id`,`branch_id`,`multi_branch_id`, `brand_id`, `Currency_ID`, `Product_Quantity`, `Product_Cost`
                            , `UOM_ID`, `default_view_uom_id`, `default_view_rate` , `Product_VAT`, `vat_percent`, `Product_Limit_Discount`, `Status_ID`, `Logged_ID`, `Product_PLU`, `PLU_Type`, `Product_Arabic_Name` `multi_branch_id`,)
                        SELECT tmp_pro_code, tmp_pro_name, tmp_cat_id, if(tmp_printer_id= '',null,tmp_printer_id),if(tmp_branch_id= '',null,tmp_branch_id), if(tmp_multi_branch_id= '',null,tmp_multi_branch_id), tmp_brand_id, '" . smc_session()['local_currency'] . "', 0, tmp_def_uom_pro_cost
                            , tmp_uom_id_1, tmp_uom_id_1, 1, if(tmp_vat_per > 0, 1, 0), tmp_vat_per, '{$tmp_limit_disc}', 1, '" . Session::getUserID() . "', {$plu_type_fld}, 'N', ''
                        from `{$table_name}` where tmp_is_error <> '1' and isNULL(tmp_pro_exist_id) ");
            //fill the new inserted products ids which is not error and not already exist before
            $this->db->query("update `{$table_name}` t
                        inner join tbl_stock_products p on tmp_pro_code = Product_Code and tmp_pro_name = Product_Name
                    set tmp_pro_insert_id = Product_ID where tmp_is_error <> '1' and isNULL(tmp_pro_exist_id) ");
            //insert to the uoms conversion the new units, and insert the new related prices
            for ($i = 1; $i <= $max_uom_no; $i++) {
                $new_pro_uom_cond = " tmp_is_error <> '1' and !isNULL(tmp_pro_insert_id) and tmp_uom_id_{$i} > 0 ";
                $this->db->query("INSERT INTO `tbl_uom_conversions` (`uom_from`, `conversion_amount`, `uom_to`, `Product_ID`
                            , `is_default`, `Bar_Code`, `additional_barcodes`)
                        SELECT tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_id_1, tmp_pro_insert_id
                            , " . ($i == 1 ? '1' : '0') . ", if(tmp_uom_barcode_{$i} <> '', tmp_uom_barcode_{$i}, null), tmp_uom_add_barcode_{$i}
                        from `{$table_name}` where {$new_pro_uom_cond} ");
                for ($j = 1; $j <= count($class_price_arr); $j++) {
                    $price_class_id = $class_price_arr[$j];
                    $price_curr_id = $class_curr_arr[$price_class_id];
                    $this->db->query("INSERT INTO `tbl_item_price_by_classes` (`Class_ID`, `Product_ID`, `UOM_ID`, `Product_Price`
                            , `Currency_ID`, `Pricing_Date`, `Status_ID`, `Logged_ID`)
                        SELECT {$price_class_id}, tmp_pro_insert_id, tmp_uom_id_{$i}, tmp_uom_price_{$i}_{$j}
                             , {$price_curr_id}, '{$today_date}', 1, '" . Session::getUserID() . "'
                        from `{$table_name}` where {$new_pro_uom_cond} ");
                }
            }
        }
        //insert to the location if there is quantities use the default uom, local currency, .. 
        //here to update the new inserted added products or even exist already inserted products
        $query = $this->db->query("select if(isNULL(tmp_pro_exist_id), tmp_pro_insert_id, tmp_pro_exist_id) as pro_id, tmp_uom_id_1 as uom_id, tmp_def_uom_pro_qty as qty, tmp_def_uom_pro_cost as cost
            from `{$table_name}` where tmp_is_error <> '1' and (!isNULL(tmp_pro_insert_id) || !isNULL(tmp_pro_exist_id)) and tmp_def_uom_pro_qty > 0 ");
        if ($this->db->rowsno($query)) {
            $qty_data_arr = array('Products' => array());
            while ($row = $this->db->assoc($query)) {
                $qty_data_arr['Products'][] = array('Product_ID' => $row['pro_id'], 'UOM_ID' => $row['uom_id'], 'Item_Quantity' => $row['qty']
                    , 'Depot_ID' => (smc_session()['user_accounts']['depot_id'] ? smc_session()['user_accounts']['depot_id'] : smc_session()['default_depot_id'])
                    , 'Currency_ID' => smc_session()['local_currency'], 'Item_Cost' => $row['cost']);
            }
            $warehouseDepot = new WarehouseDepot;
            //we must stop start transaction, commit, rollback,..!! since we use internal methods like below in warehouose depot 
            //so if in that method we make rollback or commit we don't know since $this->db is static and it is the same instance
            //so now if there is error inside warehouseDepot class will continue but here below when check db. error it will rollbck
            $warehouseDepot->stop_transaction_start_end = true;
            $warehouseDepot->setData($qty_data_arr)->addProductLocation();
        }
        //now we must update the already exist products where we already make sure that it is the with the same default uom
        if (!$upload_qty_cost_only) {
            $exst_pro_cond = " tmp_is_error <> '1' and !isNULL(tmp_pro_exist_id) ";
            $this->db->query("update tbl_stock_products p
                        inner join `{$table_name}` t on p.Product_ID = t.tmp_pro_exist_id 
                    set `Product_Name` = tmp_pro_name, `Category_ID` = tmp_cat_id, `printer_id` = if(tmp_printer_id='',null,tmp_printer_id)
                        ,`branch_id`=if(tmp_branch_id='',null,tmp_branch_id), `multi_branch_id`=if(tmp_multi_branch_id='',null,tmp_multi_branch_id), `brand_id` = tmp_brand_id, `Product_VAT` = if(tmp_vat_per > 0, 1, 0), `vat_percent` = tmp_vat_per
                    where {$exst_pro_cond} ");
            //insert the new uoms conversion or update exist for the already exist products, and insert/update the new related prices
            for ($i = 1; $i <= $max_uom_no; $i++) {
                $exst_pro_uom_cond = $exst_pro_cond . " and tmp_uom_id_{$i} > 0 ";
                //here duplication will occur only if same product/uom but will not occur on barcode since we make checking before on barcode duplication
                //if it is exist we can not change the conversion amount/rate or we must check if not used we can change it but if used can not change it.
                $this->db->query("INSERT INTO `tbl_uom_conversions` (`uom_from`, `conversion_amount`, `uom_to`, `Product_ID`
                        , `is_default`, `Bar_Code`, `additional_barcodes`)
                    SELECT tmp_uom_id_{$i}, tmp_uom_rate_{$i}, tmp_uom_id_1, tmp_pro_exist_id
                        , " . ($i == 1 ? '1' : '0') . ", tmp_uom_barcode_{$i}, tmp_uom_add_barcode_{$i}
                    from `{$table_name}` where {$exst_pro_uom_cond} 
                        ON DUPLICATE KEY UPDATE `Bar_Code` = tmp_uom_barcode_{$i}, additional_barcodes = tmp_uom_add_barcode_{$i} ");
                //
                for ($j = 1; $j <= count($class_price_arr); $j++) {
                    $price_class_id = $class_price_arr[$j];
                    $price_curr_id = $class_curr_arr[$price_class_id];
                    $this->db->query("INSERT INTO `tbl_item_price_by_classes` (`Class_ID`, `Product_ID`, `UOM_ID`, `Product_Price`
                        , `Currency_ID`, `Pricing_Date`, `Status_ID`, `Logged_ID`)
                    SELECT {$price_class_id}, tmp_pro_exist_id, tmp_uom_id_{$i}, tmp_uom_price_{$i}_{$j}
                         , {$price_curr_id}, '{$today_date}', 1, '" . Session::getUserID() . "'
                    from `{$table_name}` where {$exst_pro_uom_cond} 
                        ON DUPLICATE KEY UPDATE `Product_Price` = tmp_uom_price_{$i}_{$j}, Currency_ID = {$price_curr_id} ");
                }
            }
        }      
        
        //
        //die(print_r($this->db->error(), true));
        $error = $this->db->error();
        $html = "";
        $is_error = '0';
        if (empty($error)) {
            $this->db->query('COMMIT');
            //create error csv if there is
            $query = $this->db->query("SELECT tmp_excel_row_no, tmp_pro_code, tmp_pro_name, tmp_error_text 
                                    FROM `{$table_name}`  where tmp_is_error = '1' order by tmp_excel_row_no asc");
            if ($this->db->rowsno($query)) {
                $import_error_csv_path = SYSTEM_PATH . 'import-product-error.csv';
                $output = fopen($import_error_csv_path, 'w');
                //output the column header
                fputcsv($output, array('Excel Row Number', 'Code', 'Name', 'Error'));
                while ($row = $this->db->assoc($query))
                    fputcsv($output, $row);
                fclose($output);
                $html = "<iframe src='" . SITE_LINK . "/StockAjax/importProducts/?action=error_excel&path=" . urlencode($import_error_csv_path) . "' style='display:none;width:0px;height:0px;' ></iframe>";
            }
        } else {
            $this->db->query('ROLLBACK');
            $is_error = '1';
            $html = array_unique($error);
        }
        $this->db->query("DROP TABLE IF EXISTS `{$table_name}`");
        //
        return array('is_error' => $is_error, 'html' => $html);
    }

*/ 
    public function import_recipe() {
        //when finish to download an error excel if there is
        if (!empty($_GET['action']) && $_GET['action'] == 'error_excel') {
            $csv_err_file = empty($_GET['path']) ? '' : $_GET['path'];
            if (!empty($csv_err_file) && file_exists($csv_err_file) && strtolower(pathinfo($csv_err_file, PATHINFO_EXTENSION)) == 'csv') {
                header('Content-Type: text/csv; charset=utf-8');
                header('Content-Description: File Transfer');
                header('Content-Disposition: attachment; filename="' . basename($csv_err_file) . '"');
                header('Expires: 0');
                header('Content-Length: ' . filesize($csv_err_file));
                readfile($csv_err_file);
                unlink($csv_err_file);
            }
            exit;
        }
        //
        require dirname(__FILE__) . '/../PHPExcel/PHPExcel/IOFactory.php';
        $Fileextension = $_FILES['Document_File_Name']['tmp_name'];
        $excel = PHPExcel_IOFactory::load($Fileextension);
        $writer = PHPExcel_IOFactory::createWriter($excel, 'CSV');
        $writer->setDelimiter(";");
        $writer->setEnclosure("");
        self::convertxlsxtoCSV($Fileextension, 'output.csv');
        //
        $this->db->query('START TRANSACTION');
        //fill needed data array like uom, category,..
        $uom_arr = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_uom');
        while ($row = $this->db->assoc($query))
            $uom_arr[strtolower($row['UOM_Name'])] = $row['UOM_ID'];
        $product_arr = array();
        $products_query = $this->db->query('SELECT * FROM tbl_stock_products');
        while ($row = $this->db->assoc($products_query))
            $product_arr[strtolower($row['Product_Name'])] = $row['Product_ID'];
        //
        $err = "";
        $is_insert = '0';
        if (($getfile = fopen('output.csv', "r"))) {
            fgetcsv($getfile, 1000, ",");   //escape first row/header
            $row_no = 2;
            $old_product_id = null;
            $recepie_arr = array();
            $main_qty_arr = array();
            $recepie_err = array();
            while (($excel_row = fgetcsv($getfile, 1000, ","))) {
                //trim the data
                array_walk_recursive($excel_row, function(&$value, $index) {
                    $value = trim($value);
                });
                //inset the row to the temp table
                $data_arr = array();
                $product_main = strtolower($excel_row[0]);
                //in case of main product is empty then it is continue from previous row
                if (empty($product_main) && !empty($old_product_id))
                    $data_arr[0] = $old_product_id; //product main
                else
                    $data_arr[0] = (isset($product_arr[$product_main]) ? $product_arr[$product_main] : 0);
                $crnt_product_id = $data_arr[0];
                //if there error related to this product in any ingradients then exclude it
                if (isset($recepie_err[$crnt_product_id])) {
                    if (isset($recepie_arr[$crnt_product_id]))
                        unset($recepie_arr[$crnt_product_id]);
                    continue;
                }
                $product_sub = strtolower($excel_row[1]);
                $data_arr[1] = (isset($product_arr[$product_sub]) ? $product_arr[$product_sub] : 0); //product sub
                $uom_name = strtolower($excel_row[2]);   // uom
                $data_arr[2] = (isset($uom_arr[$uom_name]) ? $uom_arr[$uom_name] : 0);    //uom id
                $data_arr[3] = floatval($excel_row[3]);    //current qty
                $data_arr[4] = Product::getConvertedQuantity($data_arr[2], $data_arr[3], $data_arr[1]);  //default qty
                $data_arr[5] = '-';  //operation
                $produced_qty = floatval($excel_row[4]);
                $produced_qty = empty($produced_qty) ? 1 : $produced_qty;
                //
                if (($data_arr[0] == $data_arr[1]) || $data_arr[0] == 0 || $data_arr[1] == 0 || $data_arr[2] == 0 || $data_arr[3] <= 0) {
                    $recepie_err[$data_arr[0]] = $data_arr[0];
                    $err .= "Check Excel Row Number [{$row_no}]: ";
                    if ($data_arr[0] == 0)
                        $err .= "Main Product does not exist";
                    elseif ($data_arr[1] == 0)
                        $err .= "Recipe Product does not exist";
                    elseif ($data_arr[0] == $data_arr[1])
                        $err .= "Main and Recipe Product are same!";
                    elseif ($data_arr[2] == 0)
                        $err .= "Uom does not exist";
                    elseif (floatval($data_arr[3]) <= 0)
                        $err .= "Wrong Quantity";
                    $err .= "<br>";
                } else {
                    $recepie_arr[$crnt_product_id][] = $data_arr;
                    if ($old_product_id != $crnt_product_id) //first row
                        $main_qty_arr[$crnt_product_id] = $produced_qty;
                }
                //
                $old_product_id = $crnt_product_id;
                $row_no++;
            }
            //
            $insert_hdr = " INSERT INTO `tbl_products_link` (`main_product_id`, `sub_product_id`,`UOM_ID`, `current_quantity`, `quantity`, `operation`)";
            foreach ($recepie_arr as $main_product_id => $product_recepie_arr) {
                //delete old recepie first
                $this->db->prepare_Stmt("delete from tbl_products_link where main_product_id = ? and operation = '-' ", [&$main_product_id]);
                $this->db->prepare_Stmt("update tbl_stock_products set recipe_qty = ? where Product_ID = ?", [&$main_qty_arr[$main_product_id], &$main_product_id]);
                foreach ($product_recepie_arr as $recepie_row) {
                    $insert_str = $insert_hdr . " values (" . substr(str_repeat(",?", count($recepie_row)), 1) . ") ";
                    $this->db->prepare_Stmt($insert_str, $recepie_row);
                }
                $is_insert = '1';
            }
        }
        //
        $error = $this->db->error();

        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
            $err .= "<br/>Db. Error<br/>" . implode("<br/>", array_unique($error));
        }
        //
        return array('is_insert' => $is_insert, 'err_msg' => $err);
    }

    public function convertxlsxtoCSV($infile, $outfile) {
        $fileType = PHPExcel_IOFactory::identify($infile);
        $objReader = PHPExcel_IOFactory::createReader($fileType);

        $objReader->setReadDataOnly(true);
        $objPHPExcel = $objReader->load($infile);

        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
        $objWriter->save($outfile);
    }

    public function getUOM() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_stock_uom');
        while ($row = $this->db->assoc($query)) {
            $data[$row['UOM_ID']] = $row;
        }
        return $data;
    }

    public function getCompts() {
        $data = array();
        $query = $this->db->query('SELECT * FROM tbl_compts');
        while ($row = $this->db->assoc($query)) {
            $data[$row['compts_id']] = $row;
        }
        return $data;
    }

    public function getBarcodebyUom($uom_id, $product_id) {
        $data = array();
        $query = $this->db->query('SELECT Bar_Code from tbl_uom_conversions where Product_ID = "' . $product_id . '" and uom_from = "' . $uom_id . '" ');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getProductsForCustomers($PID, $class_id, $customer_id, $uom_id) {
        //        $class_id = smc_session()['pricing_class_id'];
        //        if ($customer_id != 0) {
        //            $query_cust = $this->db->query('select Class_ID from tbl_customers where Customer_ID = "' . $customer_id . '"');
        //            $class_id = $this->db->assoc($query_cust)['Class_ID'];
        //        }
        //         $Products[$x]['Product_Limit_Discount'],
        //                                    $Products[$x]['is_tax'],
        //                                    $Products[$x]['product_color'],
        //                                    $Products[$x]['last_price'],
        //                                    $Products[$x]['ttc_price']
        $is_ttc = 0;
        $currency_id = 0;
        $tax_amount = 0;
        if (!empty($class_id)) {
            $query_class = $this->db->query('select is_ttc,Currency_ID,tax_amount from tbl_pricing_class where Class_ID = "' . $class_id . '"');
            $data_class = $this->db->assoc($query_class);
            $is_ttc = $data_class['is_ttc'];
            $currency_id = $data_class['Currency_ID'];
            $tax_amount = $data_class['tax_amount'];
        }
        $depot_id = smc_session()['default_depot_id'];
        $query = $this->db->query('select count(*) as mycount,product_id 
                from tbl_product_options where product_id ="' . $PID . '"');
        $option_count = $this->db->assoc($query)['mycount'];
        $link_count = 0;
        if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0) {
            $query = $this->db->query('select count(*) as mycount,main_product_id 
                from tbl_products_link where main_product_id ="' . $PID . '" ');
            $link_count = $this->db->assoc($query)['mycount'];
        }
        $cond_branch = '';
         if($this->perm->hasPermission('Branches')){
             $cond_branch  = '';
        }else{
            $cond_branch .= ' and (multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '" ) ' ;
        }
       
        $data = array();
        $query = $this->db->query('SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate,
                                        p.branch_id,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name,
                                        p.Product_Limit_Discount,
                                        p.is_tax,
                                        p.product_color,
                                        p.row_number,
                                        p.column_number,
                                        p.page_number,
                                        p.is_expiry,p.is_lot,p.is_serial,
                                        p.force_change_price,
                                        p.duration_reservation,
                                        if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity) AS Quantity,
                                        p.Product_VAT AS VAT,
                                        p.vat_percent,p.vat2_percent,
                                        p.Category_ID,
                                        p.UOM_ID,
                                        p.hide_pos1,
                                        u.Bar_Code,
                                        u.conversion_amount,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,p.is_service,p.recipe_qty
                                    FROM
                                        tbl_stock_products p	
                                    left  join tbl_stock_product_location l on l.Location_Product_ID = p.Product_ID and l.Product_Depot_ID = "' . $depot_id . '"

                                    LEFT JOIN
                                        uom_conversions u
                                    ON 
                                        u.Product_ID = p.Product_ID and u.uom_from = "' . $uom_id . '"
                                    WHERE

                                        p.Status_ID = 1
                                    AND 
                                        p.Product_ID = "' . $PID . '"  
                                    
                                        ' . $cond_branch . ' 
                                    GROUP BY p.Product_ID
                                ');
        while ($row = $this->db->assoc($query)) {
            $row['has_optional'] = !empty($option_count) ? 1 : 0;
            $row['is_pos_disabled'] = 0;
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0 && $row['Quantity'] <= 0 && empty($option_count) && empty($link_count)) {
                $row['is_pos_disabled'] = 1;
            }
            $row['uom_conv'] = self::get_uom_conv($PID, $uom_id);
            $row['Price'] = self::get_product_price($PID, $class_id, $uom_id);
            $row['disc'] = self::get_prod_disc_by_class($PID, $class_id, $uom_id);
            $row['Currency_ID'] = $currency_id;
            $row['tax_amount'] = $row['is_tax'] == 1 ? $tax_amount : 0;
            if($row['is_rate'] == 1){
                $row['Price']= $this->change_product_rate($row['Price']);
            }
            $row['ttc_price'] = $row['Price'];
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                    $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                }else{
                    $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
    
                }
            }
            $row['last_cost'] = $row['conversion_amount'] * (smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? CommonBusiness::viewCurrentProductCost($PID) : CommonBusiness::viewLastProductCost($PID));
            $row['last_price'] = 0;
            if (!is_null($customer_id) && $this->perm->hasPermission('view_last_price_pos')) {
                $last_price = CommonBusiness::viewLastProductCustomerClassPrice($row['ID'], $customer_id, $class_id);
                $row['last_price'] = $last_price * $row['conversion_amount'];
            }
            $row['Quantity'] = $row['Quantity'] / $row['conversion_amount'];

            $data[] = $row;
        }
        return $data;
    }

    public function addScale() {
        $this->db->prepare_Stmt('insert into tbl_scale (scale_name,scale_ip,class_id,scale_type,scale_properties) 
            values (?,?,?,?,?)', [&$this->info['scale_name'], &$this->info['scale_ip'],
            &$this->info['class_id'], &$this->info['scale_type'], &$this->info['scale_properties']]);
        $error = $this->db->error();
        return $error;
    }

    public function updateScale() {
        $this->db->prepare_Stmt('update tbl_scale set scale_name = ?, scale_ip = ?,class_id=?,scale_type=?,
            scale_properties = ?
            where scale_id = ?', [&$this->info['scale_name'], &$this->info['scale_ip'],
            &$this->info['class_id'], &$this->info['scale_type'], &$this->info['scale_properties'], &$this->info['scale_id']]);
        $error = $this->db->error();
        return $error;
    }

    public function deleteScale() {
        $this->db->prepare_Stmt('delete from tbl_scale where scale_id = ?', [&$this->info['scale_id']]);
        $error = $this->db->error();
        return $error;
    }

    public function getKeysProducts($id) {
        $data = array();
        $query = $this->db->query('select k.key_id,p.Product_ID,p.Product_Name,p.Product_PLU from tbl_product_keys k join tbl_stock_products p on p.Product_ID = k.Product_ID and scale_id = "' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            $data[$row['key_id']] = $row;
        }
        return $data;
    }

    public function assign_product_key() {
        $this->db->query('START TRANSACTION');
        $scale_query = $this->db->query('select * from tbl_scale where scale_id = "' . $this->info['scale_id'] . '"');
        $scale_row = $this->db->assoc($scale_query);
        //
        $plu_query = $this->db->query('select Product_PLU from tbl_stock_products where Product_ID = "' . $this->info['pid'] . '"');
        $plu = $this->db->assoc($plu_query)['Product_PLU'];
        $data = [
            &$this->info['pid'],
            &$this->info['key_id'],
            &$this->info['scale_id'],
            &$this->info['pid'],
            &$this->info['key_id'],
            &$this->info['scale_id']
        ];
        $this->db->prepare_Stmt('insert into tbl_product_keys (product_id,key_id,scale_id) values(?,?,?) on duplicate key 
            update  product_id = ? , key_id = ? ,  scale_id = ? ', $data);
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
            if (smc_session()['activate_scale'] == 1) {
                $scale = scale::scale_obj($scale_row);
                $scale->assign_product_key($this->info['key_id'], $plu);
            }
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function unregister_product_key() {
        $this->db->query('START TRANSACTION');
        $scale_query = $this->db->query('select * from tbl_scale where scale_id = "' . $this->info['scale_id'] . '"');
        $scale_row = $this->db->assoc($scale_query);
        //
        $plu = 0;
        $data = [&$this->info['key_id'], &$this->info['scale_id']];
        $this->db->prepare_Stmt('update tbl_product_keys set  product_id = NULL where key_id = ? and  scale_id = ? ', $data);
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
            if (smc_session()['activate_scale'] == 1) {
                $scale = scale::scale_obj($scale_row);
                $scale->assign_product_key($this->info['key_id'], $plu);
            }
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function getSkipKeysProducts() {
        $data = array();
        $query = $this->db->query('select 
                                        p.Product_ID,
                                        p.Product_Name,
                                        p.row_number,
                                        p.column_number,
                                        p.product_color
                                    from tbl_stock_products p
                                    where p.Category_ID = "' . $this->info['category_id'] . '" 
                                    and page_number ="' . $this->info['page_number'] . '"');
        while ($row = $this->db->assoc($query)) {
            $data[$row['row_number']][$row['column_number']] = $row;
        }
        return $data;
    }

    public function unregister_product_skip_key() {
        $data = [
            &$this->info['product_id']
        ];
        $this->db->prepare_Stmt('update tbl_stock_products set row_number=0,column_number=0,page_number=0 where  Product_ID= ?', $data);
        $error = $this->db->error();
        return $error;
    }

    public function assign_product_skip_key() {
        $data = [
            &$this->info['row_number'],
            &$this->info['column_number'],
            &$this->info['page_number'],
            &$this->info['product_color'],
            &$this->info['product_id']
        ];
        $this->db->prepare_Stmt('update  tbl_stock_products set  row_number=?,column_number=?,page_number=?,product_color=? where Product_ID = ?', $data);
        $error = $this->db->error();
        return $error;
    }

    //    public function getProductCategory(){
    //        $products_query = $this->db->query('select ');
    //        
    //    }


    public function searchBarcodeforPOS($barcode, $class_id, $depot_id, $type = null, $customer_id = null, $from_product_page = null) {
        if($from_product_page == 'true'){
            $class_query = $this->db->query("select * from tbl_default_settings where `setting_name` = 'pricing_class_id' ");;
            $class_id = $this->db->assoc($class_query)['setting_value'];
        }
        //        $class_id = smc_session()['pricing_class_id'];
        //        if ($customer_id != 0) {
        //            $query_cust = $this->db->query('select Class_ID from tbl_customers where Customer_ID = "' . $customer_id . '"');
        //            $class_id = $this->db->assoc($query_cust)['Class_ID'];
        //        }
        $condition = '';
        if (!is_null($type)) {
            $condition .= ' and p.Product_Type in(0,' . $type . ')';
        }
        //        echo !empty($depot_id) ? 'not empty' : 'empty';
      if (smc_session()['default_setting']['show_products_from_all_branches'] == 0 && $from_product_page == 'false') {
            $depot_id = smc_session()['user_accounts']['depot_id'];
            $branch_id = CommonBusiness::getBranchByDepot($depot_id);
      }     
              
      if (smc_session()['default_setting']['show_products_from_all_branches'] == 0) {
        if($this->perm->hasPermission('Branches')){
            $condition .= '';
        }else{
            $condition .= ' and (p.multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR p.multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '")';
        }
    }
        $is_ttc = 0;
        $currency_id = 0;
        $tax_amount = 0;

        //        echo '==='.$depot_id.'==';
        if (!empty($class_id)) {
            $query_class = $this->db->query('select is_ttc,Currency_ID,tax_amount from tbl_pricing_class where Class_ID = "' . $class_id . '"');
            $class_data = $this->db->assoc($query_class);
            $is_ttc = $class_data['is_ttc'];
            $currency_id = $class_data['Currency_ID'];
            $CurrencySymbol =  CurrencyFactory::getCurrencySymbol($currency_id);
            $tax_amount = $class_data['tax_amount'];
        }
        //barcode format for plu scale: I: ignore, P: Price, B: Barcode (PLU)
        $barcode_format = strtoupper(smc_session()['default_setting']['scale_barcode_format']);
        $price_start = $price_length = 0;
        if (strpos($barcode_format, 'P') !== false) {
            $price_start = strpos($barcode_format, 'P') + 1;
            $price_length = strrpos($barcode_format, 'P') + 2 - $price_start;
        }
        $barcode_start = $barcode_length = 0;
        if (strpos($barcode_format, 'B') !== false) {
            $barcode_start = strpos($barcode_format, 'B') + 1;
            $barcode_length = strrpos($barcode_format, 'B') + 2 - $barcode_start;
        }
        //
        $query = $this->db->query($x = 'SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate ,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name,
                                        p.Product_Quantity AS Quantity,
                                        p.Product_VAT AS VAT,
                                        p.vat_percent,p.vat2_percent,
                                        p.Category_ID,
                                        p.is_tax,p.is_lot,p.is_serial,
                                        p.UOM_ID,
                                        u.Bar_Code,
                                        p.Product_Limit_Discount,
                                        u.conversion_amount,def_uom.UOM_Name as default_uom_name,
                                        p.is_expiry,p.PLU_Type,p.force_change_price,p.duration_reservation,
                                         ' . (!empty($depot_id) ? 'if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)' : 'p.Product_Quantity') . ' AS stock_qty,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                        if(p.PLU_Type <> "P",0,(substr("' . $barcode . '",' . $price_start . ',' . $price_length . ')+0)) as unit_price,
                                        if(p.PLU_Type <> "P","1",((substr("' . $barcode . '",' . $price_start . ',' . $price_length . ')+0))) as unit_qty,
                                        p.branch_id,
                                        p.is_service,p.recipe_qty,def_view_uom.UOM_Name as def_view_uom_name
                                    from
                                        tbl_stock_products p	
                                        inner join tbl_stock_uom def_uom on def_uom.UOM_ID = p.UOM_ID
                                        inner join tbl_stock_uom def_view_uom on def_view_uom.UOM_ID = p.default_view_uom_id
                                    LEFT JOIN
                                        uom_conversions u
                                    ON 
                                        u.Product_ID = p.Product_ID
                                    left  join tbl_stock_product_location l 
                                    on l.Location_Product_ID = p.Product_ID 
                                    and l.Product_Depot_ID = "' . $depot_id . '"
                                    WHERE
                                    ((
                                        concat(",",u.Bar_Code,",",u.additional_barcodes,",") LIKE "%,' . $barcode . ',%"
                                        and p.PLU_Type <> "P"
                                    )
                                    or
                                    (
                                        u.Bar_Code = (substr("' . $barcode . '",' . $barcode_start . ',' . $barcode_length . ')+0)
                                        and p.PLU_Type = "P"
                                    ))
                                    ' . $condition . '
                                    GROUP BY p.Product_ID
                                    order by p.PLU_Type asc /*make priority to non weightable products*/
                                ');
        $barcode_decimal_point_number = isset(smc_session()['default_setting']['barcode_decimal_point_number']) ? smc_session()['default_setting']['barcode_decimal_point_number'] : 1;
        if($barcode_decimal_point_number == 0 || $barcode_decimal_point_number == null || empty($barcode_decimal_point_number) ){
            $barcode_decimal_point_number = 1;
        }
        if($barcode_decimal_point_number !=1 && $barcode_decimal_point_number % 10 != 0){
            $barcode_decimal_point_number = 1;
        }

        $local_currency_query = $this->db->query('SELECT * FROM `tbl_default_settings` WHERE `setting_name` = "local_currency"        ');
        $local_currency_row = $this->db->assoc($local_currency_query)['setting_value'];

        $second_currency_query = $this->db->query('SELECT * FROM `tbl_default_settings` WHERE `setting_name` = "second_currency"        ');
        $second_currency_row = $this->db->assoc($second_currency_query)['setting_value'];

        $local_currency_sympl_query = $this->db->query('SELECT * FROM `tbl_common_currency` WHERE `Currency_ID` = '.$local_currency_row.'       ');
        $local_currency_sympl_row = $this->db->assoc($local_currency_sympl_query)['Currency_Symbol'];

        $second_currency_sympl_query = $this->db->query('SELECT * FROM `tbl_common_currency` WHERE `Currency_ID` = '.$second_currency_row.'       ');
        $second_currency_sympl_row = $this->db->assoc($second_currency_sympl_query)['Currency_Symbol'];

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


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

        if (!empty($row)) {
            $row['has_optional'] = 0;
            $row['is_pos_disabled'] = 0;
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0 && $row['stock_qty'] <= 0) {
                $row['is_pos_disabled'] = 1;
            }
            $row['tax_amount'] = $row['is_tax'] == 1 ? $tax_amount : 0;
            
            $row['Price'] = self::get_product_price($row['ID'], $class_id, $row['Product_UOM']);
            $row['copy_Price'] = (float) $row['Price'] ;

            
            if($row['is_rate'] == 1){
                $row['Price'] = $this->change_product_rate($row['Price']);
             }

            
            $row['disc'] = self::get_prod_disc_by_class($row["ID"], $class_id, $row['Product_UOM']);
            $row['unit_price'] = $row['PLU_Type'] != 'P' ? $row['Price'] : $row['unit_price'];
            $row['unit_qty'] = $row['PLU_Type'] == 'P' ? ($row['unit_qty']/$barcode_decimal_point_number) / $row['Price'] : $row['unit_qty'];
            $row['unit_qty'] = CommonFunctions::public_round_number($row['unit_qty']);
            $row['ttc_price'] = $row['Price'];
            $row['CurrencySymbol'] = $CurrencySymbol;
            $row['current_cost'] = CommonBusiness::viewCurrentProductCost($row['ID']);
            $row['Currency_ID'] = $currency_id;
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                    $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                }else{
                    $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));    
                }
            }
            $row['last_price'] = 0;
            $row['last_cost'] = $row['conversion_amount'] * (smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? $row['current_cost'] : CommonBusiness::viewLastProductCost($row['ID']));
            if (!is_null($customer_id) && $this->perm->hasPermission('view_last_price_pos')) {
                $last_price = CommonBusiness::viewLastProductCustomerClassPrice($row['ID'], $customer_id, $class_id);
                $row['last_price'] = $last_price * $row['conversion_amount'];
            }
            $row['stock_qty'] = $row['stock_qty'] / $row['conversion_amount'];
            $row['loc'] = '';
            if (!is_null($depot_id) && smc_session()['default_setting']['display_shelf_locations'] == 1) {
                $query_dep = $this->db->query('select GROUP_CONCAT(d.shelf_name separator ",") as loc,s.product_id
                from tbl_product_shelf s
                join tbl_shelfs_depot d on s.shelf_depot_id = d.shelf_depot_id 
                where s.product_id = "' . $row['ID'] . '"  and s.depot_id = "' . $depot_id . '" 
                    group by s.product_id');
                $row_shelf = $this->db->assoc($query_dep);
                $row['loc'] = $row_shelf['loc'];
            }
            if ($row['is_expiry'] == 1 && !empty(smc_session()['default_setting']['activate_oldest_expiry_selected'])) {
                $exp_data = self::get_product_expiries($row['ID']);
                $row['oldest_expiry'] = $exp_data[$row['ID']];
            }

            $query = $this->db->query('select count(*) as mycount,product_id 
                from tbl_product_options where product_id ="' . $row['ID'] . '"');
            $option_count = $this->db->assoc($query)['mycount'];

            $row['has_optional'] = !empty($option_count) ? 1 : 0;
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0 && !empty($option_count)) {
                $row['is_pos_disabled'] = 0;
            }
            //
            if (smc_session()['default_setting']['activate_pos_negative_sales'] == 0 && smc_session()['default_setting']['pos_cache_time_min'] == 0) {
                $query = $this->db->query('select count(*) as mycount,main_product_id 
                from tbl_products_link where main_product_id  ="' . $row['ID'] . '"');
                $link_count = $this->db->assoc($query)['mycount'];
                if (!empty($link_count))
                    $row['is_pos_disabled'] = 0;
            }
            $row['local_currency_sympl'] =  $local_currency_sympl_row;
            $row['second_currency_sympl'] =  $second_currency_sympl_row;
            $row['sec_rate'] = $exchange_rate_first_sec;
            $row['fir_rate'] = $exchange_rate_sec_first;
            if($exchange_rate_first_sec > 1){
                $row['our_rate'] = CommonFunctions::formatNumber($exchange_rate_first_sec).' L.L';

            }else{
                $row['our_rate'] = CommonFunctions::formatNumber($exchange_rate_sec_first).' L.L';

            }

            if ($local_currency_row == $row['Currency_ID']) {
                $row['sec_price'] = CommonFunctions::formatNumber(($exchange_rate_first_sec * $row['copy_Price']) + $row['copy_Price']).' '.$second_currency_sympl_row;
                $row['fir_price'] = CommonFunctions::formatNumber($row['copy_Price']).' '.$local_currency_sympl_row;

            } else if ($second_currency_row == $row['Currency_ID']) {
                $row['fir_price'] = CommonFunctions::formatNumber(($exchange_rate_sec_first * $row['copy_Price']) + $row['copy_Price']).' '.$local_currency_sympl_row;;
                $row['sec_price'] =  CommonFunctions::formatNumber($row['copy_Price']).' '.$second_currency_sympl_row;;
            }

            return $row;

        }
        //        file_put_contents(tmp_dir_path . 'barcode_scanner_text-'.date('Y-m-d').'.html', "\n<tr><td>" . date("Y-m-d H:i:s") . "</td><td>{$barcode}</td><td>" . (empty($row) ? "Barcode Not Exist" : print_r($row, true)) . "</td></tr>", FILE_APPEND);
        //        echo"<pre>";
        //        die(print_r($data));
        return $row;
    }

    public function syncScaleProducts($id) {
        $data = array('products' => array(), 'keys' => array());
        //
        $scale_query = $this->db->query('select * from tbl_scale where scale_id = "' . $id . '"');
        $scale_row = $this->db->assoc($scale_query);
        $scale_class = $scale_row['class_id'];
        //get products
        $query = $this->db->query('select p.Product_PLU, p.Product_Name, u.Bar_Code as Product_Code, p.PLU_Type, p.Product_ID, p.UOM_ID, p.Product_Arabic_Name
                                    from  tbl_stock_products p 
                                        left join tbl_uom_conversions u on (p.Product_ID = u.Product_ID and u.is_default = 1)
                                    where on_scale = 1 ');
        while ($row = $this->db->assoc($query)) {
            $row['Product_Price'] = self::get_product_price($row['Product_ID'], $scale_class, $row['UOM_ID']);
            $row['Product_Description'] = $row['Product_Arabic_Name'];
            $data['products'][$row['Product_ID']] = $row;
        }
        //
        $query = $this->db->prepare_Stmt('select * from tbl_product_keys where scale_id = "' . $id . '" ');
        while ($row = $this->db->assoc($query)) {
            if (isset($data['products'][$row['product_id']]))
                $data['keys'][$row['key_id']] = $data['products'][$row['product_id']]['Product_PLU'];
        }
        //
        if (smc_session()['activate_scale'] == 1) {
            $scale = scale::scale_obj($scale_row);
            $scale->full_register_products($data);
        }
        $error = array();
        return $error;
    }

    public function searchProductforPOS($id, $class_id, $depot_id, $customer_id = null) {
        //        $class_id = smc_session()['pricing_class_id'];
        //        if (!is_null($customer_id)) {
        //            $query_cust = $this->db->query('select Class_ID from tbl_customers where Customer_ID = "' . $customer_id . '"');
        //            $class_id = $this->db->assoc($query_cust)['Class_ID'];
        //        }edit here
        $is_ttc = 0;
        $currency_id = 0;
        if (!empty($class_id)) {
            $query_class = $this->db->query('select is_ttc,Currency_ID from tbl_pricing_class where Class_ID = "' . $class_id . '"');
            $class_data = $this->db->assoc($query_class);
            $is_ttc = $class_data['is_ttc'];
            $currency_id = $class_data['Currency_ID'];
        }
        $query = $this->db->query('SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate ,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name,
                                        p.Product_Quantity AS Quantity,
                                        ' . (!is_null($depot_id) ? 'if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)' : 'p.Product_Quantity') . ' AS stock_qty,
                                        p.Product_VAT AS VAT,
                                        p.vat_percent,p.vat2_percent,
                                        p.is_tax,p.is_lot,p.is_serial,
                                        p.UOM_ID,
                                        p.Product_Limit_Discount,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,
                                        1 as unit_qty,
                                        u.Bar_Code
                                    from
                                        tbl_stock_products p	

                                    LEFT JOIN
                                        uom_conversions u
                                    ON 
                                        u.Product_ID = p.Product_ID
                                    left  join tbl_stock_product_location l 
                                    on (l.Location_Product_ID = p.Product_ID 
                                    and l.Product_Depot_ID = "' . $depot_id . '")
                                    WHERE

                                        p.Product_ID = "' . $id . '"
                                    GROUP BY p.Product_ID
                                ');
        $row = $this->db->assoc($query);
        $row['Price'] = self::get_product_price($id, $class_id, $row['UOM_ID']);
        if($row['is_rate'] == 1){
            $row['Price']= $this->change_product_rate($row['Price']);
        }
        $row['unit_price'] = $row['Price'];
        $row['ttc_price'] = $row['Price'];
        $row['Currency_ID'] = $currency_id;
        if ($is_ttc == 1) {
            if(smc_session()['default_setting']['products_without_vat']){
                $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                $row['unit_price'] = ($row['unit_price'] * ($row['vat2_percent'] / 100))+$row['unit_price'];
                $row['unit_price'] = ($row['unit_price'] * ($row['vat_percent'] / 100))+$row['unit_price'];
            }else{
                $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
                $row['unit_price'] = $row['unit_price'] / (1 + ($row['vat2_percent'] / 100));
                $row['unit_price'] = $row['unit_price'] / (1 + ($row['vat_percent'] / 100));    
            }
        }
        $row['last_cost'] = smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? CommonBusiness::viewCurrentProductCost($id) : CommonBusiness::viewLastProductCost($id);
        if (!is_null($customer_id) && $this->perm->hasPermission('view_last_price_pos')) {
            $last_price = CommonBusiness::viewLastProductCustomerClassPrice($id, $customer_id, $class_id);
            $row['last_price'] = $last_price;
        }
        //        echo"<pre>";
        //        die(print_r($data));
        return $row;
    }

    public function resetAllScale() {
        if (smc_session()['activate_scale'] == 1) {
            $scale_query = $this->db->query('select * from tbl_scale where scale_id = "' . $this->info['scale_id'] . '"');
            $scale_row = $this->db->assoc($scale_query);
            //
            $scale = scale::scale_obj($scale_row);
            $scale->reset_all_keys();
        }
        $error = array();
        return $error;
    }

    public function checkIfProductUOMUsed($pid, $uom_id = null) {
        $cond = '';
        if (!is_null($uom_id)) {
            $cond .= ' and UOM_ID = "' . $uom_id . '"';
        }
        //check if if product is used in invoices
        $inv_query = $this->db->query('select * from tbl_invoice_products_details where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $inv_count = $this->db->rowsno($inv_query);
        if ($inv_count > 0) {
            return true;
        }
        //check if if product is used in purchases
        $pur_query = $this->db->query('select * from tbl_inventory_purchase_items where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $pur_count = $this->db->rowsno($pur_query);
        if ($pur_count > 0) {
            return true;
        }
        //check if if product is used in return
        $return_query = $this->db->query('select * from tbl_accounting_return_items where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $return_count = $this->db->rowsno($return_query);
        if ($return_count > 0) {
            return true;
        }
        if (smc_session()['default_setting']['delete_product_if_assign_adjust_only'] == 0) {
            //check if if product is used in product locations
            $location_query = $this->db->query('select * from tbl_stock_product_location l join tbl_stock_products p
            on p.Product_ID = l.Location_Product_ID where l.Location_Product_ID = "' . $pid . '"' . $cond . ' and Product_Depot_Quantity <> 0 limit 1');
            $location_count = $this->db->rowsno($location_query);
            if ($location_count > 0) {
                return true;
            }
        }
        //check if if product is used in request stock
        $recond = !is_null($uom_id) ? ' and Request_UOM = "' . $uom_id . '"' : '';
        $request_query = $this->db->query('select * from tbl_stock_request_details where Product_ID = "' . $pid . '"' . $recond . ' limit 1');
        $request_count = $this->db->rowsno($request_query);
        if ($request_count > 0) {
            return true;
        }
        //check if if product is used in sales order
        //        $sorder_query = $this->db->query('select * from tbl_garage_sales_order_details where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        //        $sorder_count = $this->db->rowsno($sorder_query);
        //        if ($sorder_count > 0) {
        //            return true;
        //        }
        //check if if product is used in purchase order
        $porder_query = $this->db->query('select * from tbl_purchase_order_details where Item_ID = "' . $pid . '"' . $cond . ' limit 1');
        $porder_count = $this->db->rowsno($porder_query);
        if ($porder_count > 0) {
            return true;
        }
        //check if if product is used in delivery notes
        $delivery_query = $this->db->query('select * from tbl_inventory_delivery_report_items where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $delivery_count = $this->db->rowsno($delivery_query);
        if ($delivery_count > 0) {
            return true;
        }
        //check if if product is used in production template
        $prod_template_query = $this->db->query('select * from tbl_production_template_details where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $prod_template_count = $this->db->rowsno($prod_template_query);
        if ($prod_template_count > 0) {
            return true;
        }
        //check if if product is used in production process
        $prod_process_query = $this->db->query('select * from tbl_production_process_details where Product_ID = "' . $pid . '"' . $cond . ' limit 1');
        $prod_process_count = $this->db->rowsno($prod_process_query);
        if ($prod_process_count > 0) {
            return true;
        }
        //check if if product is used in stock product transaction
        $stock_prod_trans_query = $this->db->query('select * from tbl_stock_product_transactions where Product_ID = "' . $pid . '"' . $cond . (smc_session()['default_setting']['delete_product_if_assign_adjust_only'] == 1 ? ' and Transaction_Type_ID not in (6,10)' : '') . ' limit 1');
        $stock_prod_trans_count = $this->db->rowsno($stock_prod_trans_query);
        if ($stock_prod_trans_count > 0) {
            return true;
        }
        //check if if product is used in stock damaged items
        $stock_damaged_query = $this->db->query('select * from tbl_damage_details where product_id = "' . $pid . '"' . $cond . ' limit 1');
        $stock_damaged_count = $this->db->rowsno($stock_damaged_query);
        if ($stock_damaged_count > 0) {
            return true;
        }

        //check if if product is used in product expense details
        $prod_expense_details_query = $this->db->query('select * from tbl_product_expense_details where part_product_id = "' . $pid . '"' . $cond . ' limit 1');
        $product_expense_details_count = $this->db->rowsno($prod_expense_details_query);
        if ($product_expense_details_count > 0) {
            return true;
        }

        if (is_null($uom_id)) {
            $all_parts = array();
            $product_part_query = $this->db->query("select * from tbl_stock_products_parts where part_product_id IN ({$pid})  or Product_ID In ({$pid}) ");
            while ($row = $this->db->assoc($product_part_query)) {
                $all_parts[] = $row['part_id'];
            }
            if (empty($all_parts))
                return false;
            $all_parts = implode(",", $all_parts);
            //check if if product is used in checklist schedule
            $checklist_schedule_query = $this->db->query("select * from tbl_checklist_schedule where Product_ID  IN ({$all_parts})  or part_id IN ({$all_parts}) limit 1");
            $checklist_schedule_count = $this->db->rowsno($checklist_schedule_query);
            if ($checklist_schedule_count > 0) {
                return true;
            }
            //check if if product is used in product expense
            $product_expenses_query = $this->db->query("select * from tbl_product_expenses where Product_ID  IN ({$all_parts}) limit 1");
            $product_expenses_count = $this->db->rowsno($product_expenses_query);
            if ($product_expenses_count > 0) {
                return true;
            }
            //check if if product is used in product property value
            $prod_property_val_query = $this->db->query("select * from tbl_product_property_values where Product_ID IN ({$all_parts}) limit 1");
            $prod_property_val_count = $this->db->rowsno($prod_property_val_query);
            if ($prod_property_val_count > 0) {
                return true;
            }
            //check if if product is used in stock product properties
            $stock_prod_prop_query = $this->db->query("select * from tbl_stock_product_properties where Product_ID IN ({$all_parts}) limit 1");
            $stock_prod_prop_count = $this->db->rowsno($stock_prod_prop_query);
            if ($stock_prod_prop_count > 0) {
                return true;
            }
            //check if if product is used in stock product parts
            $stock_prod_part_query = $this->db->query("select * from tbl_stock_products_parts where part_id IN ({$all_parts}) limit 1");
            $stock_prod_part_count = $this->db->rowsno($stock_prod_part_query);
            if ($stock_prod_part_count > 1) {
                return true;
            }
        }



        return false;
    }

    public function checkIfFamilyProductUsed($family_id) {
        $product_family_query = $this->db->query('select * from tbl_stock_products where family_id = "' . $family_id . '"');
        while ($row = $this->db->assoc($product_family_query)) {
            self::setData(['Product_ID' => $row['Product_ID']])->deleteProduct(true);
        }
    }

    public function deleteProduct($other = false) {
        $date_time = date("Y-m-d H:i:s");
        $product_exist = self::checkIfProductUOMUsed($this->info['Product_ID'], null);
        //        echo $this->info['Product_ID'].'===';
        //                echo $this->info['Product_ID'].'==';

        if ($product_exist) {
            $this->db->set_error('unable_delete_product');
            return ['unable_delete_product'];
        }
        if (!$other) {
            $this->db->query('START TRANSACTION');
        }
        $this->db->prepare_Stmt('Delete from tbl_uom_conversions where Product_ID = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_item_price_by_classes where Product_ID = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_products_link where main_product_id = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_product_criteria where Product_ID = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_product_shelf where product_id = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_product_keys where product_id = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_product_add_ons where product_id = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_stock_products_parts where part_product_id = ?', [&$this->info['Product_ID']]);
        $this->db->prepare_Stmt('Delete from tbl_stock_products where Product_ID = ?', [&$this->info['Product_ID']]);
        if (smc_session()['default_setting']['delete_product_if_assign_adjust_only'] == 1) {
            $this->db->prepare_Stmt('Delete from tbl_stock_product_transactions where Product_ID = ? and Transaction_Type_ID in (6,10)', [&$this->info['Product_ID']]);
            $this->db->prepare_Stmt('Delete from tbl_stock_products_costs where Product_ID = ?', [&$this->info['Product_ID']]);
            $this->db->prepare_Stmt('Delete from tbl_stock_product_location where Location_Product_ID = ?', [&$this->info['Product_ID']]);
        }
        $arr_prod = ['type' => 'prod', 'main_id' => $this->info['Product_ID'], 'action' => 2,
            'date_time' => $date_time, 'user_id' => smc_session()['user_logged_id']];
        CommonFunctions::add_user_log($arr_prod);
        $error = $this->db->error();

        if (!$other) {
            if (empty($error)) {
                $this->db->query('COMMIT');
            } else {
                $this->db->query('ROLLBACK');
            }
        }
        return $error;
    }

    public function getUOMByProductID($product_id, $uom_id, $depot_id, $currency_id, $class_id = null, $customer_id = null, $supp_class = '') {
        $condition = ' ';
        $rate = CurrencyFactory::getLastExRate($currency_id);
        $is_ttc = 0;
        $supp_cur_id = 0;
        $class_currency_id = $currency_id;
        if (!empty($class_id)) {
            $query_class = $this->db->query('select Currency_ID,is_ttc from tbl_pricing_class where Class_ID = "' . $class_id . '"');
            $class_row = $this->db->assoc($query_class);
            $class_currency_id = $class_row['Currency_ID'];
            $is_ttc = $class_row['is_ttc'];
            $rate = CurrencyFactory::getLastExRate($class_currency_id);
            //            $condition .= ' and p.Class_ID = "' . $class_id . '"';
        }
        //die($rate);
        if (!empty($supp_class)) {
            $query_class = $this->db->query('select Currency_ID,is_ttc from tbl_pricing_class where Class_ID = "' . $supp_class . '"');
            $class_row = $this->db->assoc($query_class);
            $supp_cur_id = $class_row['Currency_ID'];
        }
        $query = $this->db->query('SELECT u.Bar_Code,u.conversion_amount,
            if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity) / conversion_amount as qty,
            sp.vat_percent,sp.is_expiry,sp.vat2_percent
            FROM tbl_uom_conversions u join tbl_stock_products sp on sp.Product_ID = u.Product_ID  
            left join tbl_stock_product_location l on l.Location_Product_ID = sp.Product_ID and l.Product_Depot_ID ="' . $depot_id . '"
            WHERE u.Product_ID = "' . $product_id . '" AND u.uom_from = "' . $uom_id . '"' . $condition);
        if ($this->db->rowsno($query) == 0) {
            $row = array();
        } else {
            $row = $this->db->assoc($query);
            $row['Product_Price'] = self::get_product_price($product_id, $class_id, $uom_id);
            $row['disc'] = self::get_prod_disc_by_class($product_id, $class_id, $uom_id);
            $row['Currency_ID'] = $class_currency_id;
            if($row['is_rate'] == 1){
                $row['Product_Price']= $this->change_product_rate($row['Product_Price']);
            }
            $row['is_ttc'] = $is_ttc;
            $row['ttc_price'] = $row['Product_Price'];
            $row['ttc_price_local'] = $row['Product_Price'] * $rate;
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Product_Price'] * ($row['vat2_percent'] / 100))+$row['Product_Price'];
                    $row['ttc_price'] = ($row['Product_Price'] * ($row['vat_percent'] / 100))+$row['Product_Price'];
                }else{
                    $row['Product_Price'] = $row['Product_Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Product_Price'] = $row['Product_Price'] / (1 + ($row['vat_percent'] / 100));    
                }
            }
            $row['last_price'] = 0;
            $row['local_last_price'] = 0;
            //            $row['price_local'] = $row['Product_Price'] * $rate;
            $row['current_cost'] = CommonBusiness::viewCurrentProductCost($product_id);
            $cost = smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? $row['currenct_cost'] : CommonBusiness::viewLastProductCost($product_id);
            $row['last_cost'] = $cost / $rate;
            $row['local_cost'] = $cost;
            $supp_cost = self::get_product_price($product_id, $supp_class, $uom_id);
            //            echo $supp_curr_id.'===';
            $cost_in_local = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($supp_cur_id, smc_session()['local_currency'], $supp_cost);
            $row['supp_cost'] = !empty($supp_class) ? $cost_in_local : $row['current_cost'];

            if (!is_null($customer_id) && $this->perm->hasPermission('view_last_price_pos')) {
                $last_price = CommonBusiness::viewLastProductCustomerClassPrice($product_id, $customer_id, $class_id);
                $row['last_price'] = $last_price / $rate;
                $row['local_last_price'] = $last_price;
            }
        }
        return $row;
    }

    public function ReturnQtyPerDepot($items, $depot_id) {
        $data = array();
        if (empty($items))
            return $data;

        $item_str = implode(',', $items);
        //        die($item_str);
        $query = $this->db->query('select p.Product_ID,if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity) as qty from 
            tbl_stock_products p left join tbl_stock_product_location l 
            on l.Location_Product_ID = p.Product_ID and l.Product_Depot_ID ="' . $depot_id . '" where p.Product_ID in (' . $item_str . ')');
        while ($row = $this->db->assoc($query)) {
            $row['loc'] = '';
            $data[$row['Product_ID']] = $row;
        }
        if (!is_null($depot_id) && smc_session()['default_setting']['display_shelf_locations'] == 1) {
            //            $pids_arr = implode(',', $pids);

            $query_dep = $this->db->query('select GROUP_CONCAT(d.shelf_name separator ",") as loc,s.product_id
                from tbl_product_shelf s
                join tbl_shelfs_depot d on s.shelf_depot_id = d.shelf_depot_id 
                where s.product_id in (' . $item_str . ') and s.depot_id = "' . $depot_id . '" 
                    group by s.product_id');
            while ($row = $this->db->assoc($query_dep)) {
                $data[$row['product_id']]['loc'] = $row['loc'];
            }
        }
        return $data;
    }

    public function ReturnPriceByClass($items, $class_id, $customer_id = null) {
        $data = array();
        $query_class = $this->db->query('select Currency_ID,is_ttc from tbl_pricing_class where Class_ID = "' . $class_id . '"');
        $class_row = $this->db->assoc($query_class);
        $class_currency_id = $class_row['Currency_ID'];
        $is_ttc = $class_row['is_ttc'];
        $rate = CurrencyFactory::getLastExRate($class_currency_id);

        //        echo $rate.'==';
        //getLastExRate\
        $last_price_arr = array();
        if (!is_null($customer_id) && $this->perm->hasPermission('view_sales_last_price')) {
            $product_ids = array();
            if ($this->perm->hasPermission('Branches')) {
                $product_ids .= !empty($options['search_branch_id']) ? ' and p.branch_id ="' . ($options['search_branch_id']) . '"' : '';
           }else{
               $product_ids .= ' and (p.multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR p.multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '")';
           }
            foreach ($items as $item) {
                $product_ids[] = $item['pid'];
            }
            $last_price_arr = CommonBusiness::viewLastProductCustomerClassPrice($product_ids, $customer_id, $class_id);
        }
        foreach ($items as $item) {
            $query = $this->db->query('select p.Product_ID,p.is_rate,
                u.conversion_amount,p.vat_percent,p.is_expiry,p.vat2_percent,u.uom_from as uom_id from tbl_stock_products p

                left join tbl_uom_conversions u on u.uom_from = "' . $item['uid'] . '"  and p.Product_ID = u.Product_ID
                    where p.Product_ID = "' . $item['pid'] . '"');
            $row = $this->db->assoc($query);
            $row['index'] = !empty($item['index']) ? $item['index'] : '';
            $row['Product_Price'] = self::get_product_price($item['pid'], $class_id, $item['uid']);
            if($row['is_rate'] == 1){
                $row['Product_Price']= $this->change_product_rate($row['Product_Price']);
            }

            $row['is_ttc'] = $is_ttc;
            if(!smc_session()['default_setting']['products_without_vat']){
                $row['ttc_price'] = $row['Product_Price'];
            }
            $row['ttc_price_local'] = $row['Product_Price'] * $rate;
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Product_Price'] * ($row['vat2_percent'] / 100))+$row['Product_Price'];
                    $row['ttc_price'] = ($row['Product_Price'] * ($row['vat_percent'] / 100))+$row['Product_Price'];
                }else{
                    $row['Product_Price'] = $row['Product_Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Product_Price'] = $row['Product_Price'] / (1 + ($row['vat_percent'] / 100));    
                }
            }
            $row['last_price'] = 0;
            $row['local_last_price'] = 0;
            $row['price_local'] = $row['Product_Price'] * $rate;
            $cost = smc_session()['default_setting']['view_current_cost_in_pos'] == 1 ? CommonBusiness::viewCurrentProductCost($item['pid']) : CommonBusiness::viewLastProductCost($item['pid']);
            $row['last_cost'] = $cost / $rate;
            $row['local_cost'] = $cost;

            if (array_key_exists($item['pid'], $last_price_arr)) {
                $last_price = $last_price_arr[$item['pid']];
                //                $last_price = CommonBusiness::viewLastProductCustomerClassPrice($item['pid'], $customer_id, $class_id);
                $row['last_price'] = $last_price / $rate;
                $row['local_last_price'] = $last_price;
            }
            $row['class_currency_id'] = $class_currency_id;

            //            $lastprice =  CommonBusiness::viewLastProductCost($item['pid']);
            //            $row['last_cost'] = $cost / $rate;
            //            $row['local_cost'] = $cost;
            //            die(print_r($row));
            $data[] = $row;
        }
        //        die(print_r($data));
        return $data;
    }

    //    public function ReturnPriceByClass($items, $class_id) {
    //        $data = array();
    //        foreach ($items as $item) {
    //            $query = $this->db->query('select p.Product_ID,if(isnull(pc.Product_Price),0,pc.Product_Price) as Product_Price from tbl_stock_products p
    //                left join tbl_item_price_by_classes pc
    //                on pc.Product_ID = p.Product_ID
    //            and pc.Class_ID = "' . $class_id . '" 
    //                and pc.UOM_ID = "' . $item['uid'] . '" 
    //                    where p.Product_ID = "' . $item['pid'] . '"');
    //            $row = $this->db->assoc($query);
    ////            die(print_r($row));
    //            $data[] = $row;
    //        }
    ////        die(print_r($data));
    //        return $data;
    //    }
    public function getMaxProductCode() {
        $query = $this->db->query('select max(cast(`Product_Code` as unsigned)) as max_code from tbl_stock_products');
        $code = $this->db->assoc($query)['max_code'];
        return $code + 1;
    }

    public function getProductLinks($id) {
        $data = array();
        $in_items = array();
        $out_items = array();
        $query = $this->db->query('select l.*,s.Product_Name,u.UOM_Name 
            from tbl_products_link l join tbl_stock_products s on l.sub_product_id = s.Product_ID 
            join tbl_stock_uom u on u.UOM_ID = l.UOM_ID
            where main_product_id ="' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            if ($row['operation'] == '+') {
                $in_items[] = $row;
            } else {
                $out_items[] = $row;
            }
        }
        $data['in_items'] = $in_items;
        $data['out_items'] = $out_items;
        return $data;
    }

    public function productuomSearch($term = null, $page, $limit, $pid) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and u.UOM_Name LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }
        if (!empty($this->info['part'])) {
            $part_query = $this->db->query('select * from tbl_stock_products_parts where  part_id = "' . $pid . '"');
            $pid = $this->db->assoc($part_query)['part_product_id'];
        }
        if (!is_null($pid)) {
            $cond .= ' and uc.Product_ID = ? ';
            $data_filter[] = $pid;
        }

        $query = $this->db->prepare_Stmt('SELECT uom_from as id,UOM_Name as text, p.Product_ID as product_id,p.Product_Vat
            FROM tbl_uom_conversions uc join tbl_stock_products p 
            on p.Product_ID = uc.Product_ID
            join tbl_stock_uom u on uc.uom_from = u.UOM_ID where 1=1
            ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            if (!empty($this->info['ticketing_price'])) {
                $row['price'] = self::get_ticketing_price($row['product_id'], $row['id'], $row['Product_Vat']);
            }
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function get_ticketing_price($product_id, $uom_id, $product_vat) {
        $price = 0;
        $class_id = !empty(smc_session()['default_setting']['default_ticketing_class']) ? smc_session()['default_setting']['default_ticketing_class'] : (!empty(smc_session()['default_setting']['pricing_class_id']) ? smc_session()['default_setting']['pricing_class_id'] : '');
        if (!empty($class_id)) {
            $query_price = $this->db->query('
            select item_price.Product_Price,classes.is_ttc
            from tbl_item_price_by_classes item_price
            inner join tbl_pricing_class classes on classes.Class_ID = item_price.Class_ID
            where item_price.Class_ID = "' . $class_id . '" 
            and item_price.Product_ID = "' . $product_id . '"
            and item_price.UOM_ID ="' . $uom_id . '"');
            $row = $this->db->assoc($query_price);
            $price = $row['Product_Price'];
            if (empty($row['Product_Price']))
                $price = 0;
            //here always send the ttc price
            if ($product_vat > 0 && $row['is_ttc'] == 0)
                $price = $row['Product_Price'] * (1 + ($product_vat / 100));
        }
        return $price;
    }

    public function costing_report($options) {
        //$product_id,$depot_id,$date,$type,$type_id
        $cond = ' ';
        $having_cond = ' ';



        if ($this->perm->hasPermission('Depots')) {
            if (!empty($options['depot_id'])) {
                $cond .= ' and t.Depot_ID = "' . $options['depot_id'] . '"';
            }
        } else {
            $cond .= ' and t.Depot_ID ="' . (smc_session()['user_accounts']['depot_id']) . '"';
        }

        if ($this->perm->hasPermission('Branches')) {
             $cond .= !empty($options['search_branch_id']) ? ' and p.branch_id ="' . ($options['search_branch_id']) . '"' : '';
        }else{
            $cond .= ' and (p.multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR p.multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '")';
        }

        if (!empty($options['date'])) {
            $cond .= ' and t.Transaction_Date <= "' . $options['date'] . '"';
        }
        if (!empty($options['category'])) {
            $cond .= ' and p.Category_ID = "' . $options['category'] . '"';
        }
        if (!empty($options['brand_id'])) {
            $cond .= ' and p.brand_id = "' . $options['brand_id'] . '"';
        }
        if (!empty($options['supplier_id'])) {
            $cond .= ' and p.main_supplier_id = "' . $options['supplier_id'] . '"';
        }
        if (!empty($options['operation'])) {
            $having_cond .= ' having quantity ' . ($options['operation'] == 'neg' ? ' < 0 ' : ($options['operation'] == 'pos' ? ' > 0 ' : '=0'));
        } else {
            if (empty($options['show_zero_qty'])) {
                $having_cond .= ' having abs(quantity) > 0.00000001';
            }
        }
        $total_stock_value = 0;
        $sec_cost = 0;
        $data = array();
        $query = $this->db->query('SELECT t.Product_ID, p.Product_Code,p.product_second_code,
            p.Product_Name,if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id) as UOM_ID,
            sum(t.`Product_Quantity`*if(t.`Operation_Type`="+",1,-1)/if(p.default_view_uom_id=0,1,p.default_view_rate))  as quantity,u.UOM_Name,
            sum(t.`Product_Quantity`*if(t.`Operation_Type`="+",1,-1))  as default_quantity,
            if(p.default_view_uom_id=0,1,p.default_view_rate) as uom_rate, p.branch_id as branch_id
            FROM `tbl_stock_product_transactions` t join tbl_stock_products p 
            on p.Product_ID = t.Product_ID
            join tbl_stock_uom u on if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id) = u.UOM_ID
           where 1=1 ' . $cond . '  group by t.`Product_ID` ' . $having_cond);
        while ($row = $this->db->assoc($query)) {
            $data[$row['Product_ID']] = $row;
        }
        if ($options['type'] == 'price') {
            $result_data = self::get_product_price($data, $options['type_id']);
        } else {
            $result_data = self::get_unit_cost_by_method($options['type'], $options['type_id'], $data);
        }

        $data_final = array();
        foreach ($result_data as $pid => $data_row) {
             $data_row['Product_Code'] = $data[$pid]['Product_Code'];
            if (smc_session()['default_setting']['activate_search_product_second_code'] == 1) {
                $data_row['product_second_code'] = $data[$pid]['product_second_code'];
            } else {
                unset($data_row['product_second_code']);
            }
            $data_row['Product_Name'] = $data[$pid]['Product_Name'];
            $data_row['quantity'] = CommonFunctions::formatNumber($data[$pid]['quantity']);
            if ($options['type'] == 'price') {
                $data_row['uom_name'] = $data[$pid]['UOM_Name'];
            }

            $cost = ($data_row['Price'] * $data[$pid]['uom_rate']);
            $data_row['cost'] = CommonFunctions::formatNumber($cost);
            if (!empty($options['cost_filter']) && (($options['cost_filter'] == 'zero' && $cost != 0) || ($options['cost_filter'] == 'non_zero' && $cost == 0)))
                continue;
            $data_row['total_cost'] = $data_row['Price'] * $data[$pid]['default_quantity'];
            unset($data_row['Product_ID']);
            unset($data_row['UOM_ID']);
            //            unset($data_row['UOM_Name']);
            unset($data_row['default_quantity']);
            unset($data_row['uom_rate']);
            unset($data_row['branch_id']);

            $total_stock_value += $data_row['total_cost'];

            $data_row['total_cost'] = CommonFunctions::formatNumber($data_row['total_cost']);
            $sec_cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], smc_session()['default_setting']['second_currency'], $total_stock_value);

            unset($data_row['Price']);
            $data_final[] = array_values($data_row);
        }
        //        echo"<pre>";die(print_r($data_final));
        return array('data' => $data_final, 'total' => $total_stock_value, 'sec_total' => $sec_cost);
    }

    public static function get_unit_cost_by_method($type, $type_id, $product_arr) {
        //        echo "<pre>";print_r($product_arr);
        //$type (price,last_cost,cost)
        //$type_id(class_id,method_id)
        //        $db = DBConnectorFactory::loadDriver();
        //        if ($type == 'price') {
        //            $query = $db->query('select c.Product_Price,c.Product_ID 
        //                from tbl_item_price_by_classes c join tbl_stock_products p on p.Product_ID = c.Product_ID 
        //                and p.UOM_ID = c.UOM_ID where c.Class_ID = "' . $type_id . '" 
        //                    and c.Product_ID in (' . implode(',', array_keys($product_arr)) . ')');
        //            while ($row = $db->assoc($query)) {
        //                $product_arr[$row['Product_ID']]['cost'] = $row['Product_Price'];
        //                $product_arr[$row['Product_ID']]['total_cost'] = $product_arr[$row['Product_ID']]['quantity'] * $row['Product_Price'];
        //            }
        //        } else 
        if ($type == 'last_cost') {
            //            echo'hereeee';
            foreach ($product_arr as $product_id => $pr_row) {
                $cost = CommonBusiness::viewLastProductCost($product_id);
                $product_arr[$product_id]['Price'] = $cost;
                //                $product_arr[$product_id]['total_cost'] = $product_arr[$product_id]['quantity'] * $cost;
            }
        } else if ($type == 'last_cost_second') {
            foreach ($product_arr as $product_id => $pr_row) {
                $cost = CommonBusiness::viewLastProductCost($product_id, false, false);
                $product_arr[$product_id]['Price'] = $cost;
                //                $product_arr[$product_id]['total_cost'] = $product_arr[$product_id]['quantity'] * $cost;
            }
        } else {
            foreach ($product_arr as $product_id => $pr_row) {
                $cost = CommonBusiness::viewCurrentProductCost($product_id, false, $type_id);
                $product_arr[$product_id]['Price'] = $cost;
                //                $product_arr[$product_id]['total_cost'] = $product_arr[$product_id]['quantity'] * $cost;
            }
        }
        //        echo "<pre>";
        //        die(print_r($product_arr));
        return $product_arr;
    }

    //    public function insert_table_floors() {
    //        $x = array(1 => [101, 120], 2 => [201, 210], 3 => [301, 315], 4 => [401, 405], 5 => [501, 512]);
    //        foreach ($x as $i => $value) {
    //            $floor_name = 'Floor ' . $i;
    //            $this->db->prepare_Stmt('INSERT INTO `tbl_floor`( `floor_name`, `status_id`, `order_by`) values(?,1,0)', [&$floor_name]);
    //            $id = $this->db->id();
    //            for ($j = $value[0]; $j <= $value[1]; $j++) {
    //                $table_name = $j;
    //                $this->db->prepare_Stmt('INSERT INTO `tbl_table`(`table_name`, `floor_id`) values(?,?)', [&$table_name, &$id]);
    //            }
    //        }
    //        
    //    }

    public function add_edit_pricing_class() {
        $this->db->query('START TRANSACTION');
        $is_ttc = !empty($this->info['is_ttc']) && $this->info['is_ttc'] === 'on' ? 1 : 0;
        $is_virtual = !empty($this->info['is_virtual']) && $this->info['is_virtual'] === 'on' ? 1 : 0;
        $this->info['tax_amount'] = empty($this->info['tax_amount']) ? 0 : $this->info['tax_amount'];
        if ($this->info['is_supp'] == 1) {
            $this->info['supplier_id'] = $this->info['supplier_id'] == '' ? null : $this->info['supplier_id'];
        }
        if ($this->info['is_edit'] == 0) {

            $data = [
                &$this->info['Class_Name'],
                &$this->info['Currency_ID'],
                &$this->info['tax_amount'],
                &$is_ttc,
                &$is_virtual,
                &$this->info['is_supp'],
                &$this->info['supplier_id'],
            ];
            $this->db->prepare_Stmt('insert into `tbl_pricing_class`
                ( `Class_Name`, `Currency_ID`,tax_amount,is_ttc,is_virtual,type,supplier_id) 
                values (?,?,?,?,?,?,?)', $data);
            $class_id = $this->db->id();
            //	echo $this->info['sub_classes'];exit;
            if (!empty($this->info['sub_classes'])) {
                $classes = json_decode($this->info['sub_classes'], true);
                foreach ($classes as $item) {
                    $alter_data = [&$class_id, &$item['sub_class_id'], &$item['class_percent'], &$item['type']];
                    $this->db->prepare_Stmt('INSERT INTO `tbl_pricing_class_alternatives`
                    ( `main_class_id`, `sub_class_id`, `percent`,type) values(?,?,?,?)', $alter_data);
                }
            }
        } else {
            $data = [
                &$this->info['Class_Name'],
                &$this->info['Currency_ID'],
                &$this->info['tax_amount'],
                &$this->info['supplier_id'],
                &$is_ttc,
                &$is_virtual,
                &$this->info['Class_ID']
            ];
            $this->db->prepare_Stmt('update `tbl_pricing_class`
                set `Class_Name`=?, `Currency_ID`=?,tax_amount = ? ,supplier_id = ?,is_ttc=? , is_virtual=? where Class_ID =?', $data);
            $this->db->prepare_Stmt('delete from tbl_pricing_class_alternatives where main_class_id = ?', [&$this->info['Class_ID']]);
            if (!empty($this->info['sub_classes'])) {
                $classes = json_decode($this->info['sub_classes'], true);
                foreach ($classes as $item) {
                    $alter_data = [$this->info['Class_ID'], &$item['sub_class_id'], &$item['class_percent'], &$item['type']];
                    $this->db->prepare_Stmt('INSERT INTO `tbl_pricing_class_alternatives`
                    ( `main_class_id`, `sub_class_id`, `percent`,type) values(?,?,?,?)', [&$this->info['Class_ID'], &$item['sub_class_id'], &$item['class_percent'], &$item['type']]);
                }
            }
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function get_pricing_class_by_id($id) {
        $data = array('main' => array(), 'details' => array());
        $query = $this->db->query('select pc.*,cu.*,s.Supplier_Name from tbl_pricing_class pc
            join tbl_common_currency cu on cu.Currency_ID = pc.Currency_ID
            left join tbl_stock_suppliers s on s.Supplier_ID = pc.supplier_id
            where Class_ID = "' . $id . '"');
        $row = $this->db->assoc($query);
        $query_det = $this->db->query('select * from tbl_pricing_class_alternatives a
            left join tbl_pricing_class pc on a.sub_class_id = pc.Class_ID
            where main_class_id = "' . $id . '"');
        while ($det = $this->db->assoc($query_det)) {
            $data['details'][] = $det;
        }
        if (!empty($row))
            $data['main'] = $row;
        return $data;
    }
    public function submit_production_barcode() {
        $this->db->query('START TRANSACTION');
        //$flag = $this->info['brand_flag'];
        $query = $this->db->query('SELECT barcode FROM tbl_production_barcode 
        WHERE   barcode = "' . $this->info['myBarcode'] . '"');
        $count = $this->db->rowsno($query);
        if ($count == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_production_barcode
                                     (barcode,item,text_right,text_left,text_right_bo,text_left_bo)
                                     VALUES
                                    (?,?,?,?,?,?)
                                         ', [&$this->info['myBarcode'], &$this->info['item_name'], &$this->info['text_right'], &$this->info['text_left'], &$this->info['text_right_bo'], &$this->info['text_left_bo']]);
        }else{
            $this->db->prepare_Stmt('update tbl_production_barcode set item = ?,text_right=?,text_left=?,text_right_bo=?,text_left_bo=? where barcode = ? ', [ &$this->info['item_name'], &$this->info['text_right'], &$this->info['text_left'], &$this->info['text_right_bo'], &$this->info['text_left_bo'],&$this->info['myBarcode']]);

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

    }
    public function submit_production_color() {
        $this->db->query('START TRANSACTION');
        //$flag = $this->info['brand_flag'];
        $query = $this->db->query('SELECT position_name FROM tbl_production_color 
        WHERE   position_name = "' . $this->info['position'] . '"');
        $count = $this->db->rowsno($query);
        if ($count == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_production_color
                                     (color_name,position_name)
                                     VALUES
                                    (?,?)
                                         ', [&$this->info['color_name'], &$this->info['position']]);
        }else{
            $this->db->prepare_Stmt('update tbl_production_color set color_name = ?   where position_name = ? ', [ &$this->info['color_name'], &$this->info['position']]);

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

    }
    public function get_production_barcode() {
        $query = $this->db->query('SELECT * FROM tbl_production_barcode 
        WHERE   barcode = "' . $this->info['myBarcode'] . '"');
 
        $data = array();
        $data['data'] = array();
        while ($row = $this->db->assoc($query)) {
                $data['data'][] = $row;
        }
 
        return $data;

    }
    public function get_production_color() {
        $query = $this->db->query('SELECT * FROM tbl_production_color 
        WHERE   position_name = "' . $this->info['position'] . '"');
 
        $data = array();
        $data['data'] = array();
        while ($row = $this->db->assoc($query)) {
                $data['data'][] = $row;
        }
 
        return $data;

    }
    public function get_all_production_color() {
        $query = $this->db->query('SELECT * FROM tbl_production_color 
        ');
 
        $data = array();
         while ($row = $this->db->assoc($query)) {
                $data[] = $row;
        }
 
        return $data;

    }
    

    public function submitBrand() {
        $this->db->query('START TRANSACTION');
        $flag = $this->info['brand_flag'];

        if ($flag == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_brand_products
                                     (brand_name,order_nb)
                                     VALUES
                                    (?,?)
                                         ', [&$this->info['brand_name'], &$this->info['order_nb']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_brand_products
                                                 SET
                                                        brand_name =?,
                                                        order_nb =?
                                                 WHERE 
                                                        brand_id =?

                                         ', [&$this->info['brand_name'], &$this->info['order_nb'], &$this->info['brand_id']]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return array_unique($error);
    }

    public function deleteBrand() {

        $query = $this->db->prepare_stmt('select * from tbl_stock_products where brand_id = ?', [&$this->info['entry_value']]);
        $row_count = $this->db->rowsno($query);
        if ($row_count == 0) {
            $this->db->prepare_Stmt('Delete from tbl_brand_products where brand_id = ?
                                         ', [&$this->info['entry_value']]);
            $error = $this->db->error();
        } else {
            $error = CommonLanguage::getMessage('brand_used');
        }

        return $error;
    }

    public function add_edit_product_section() {
        $this->db->query('START TRANSACTION');
        if ($this->info['is_edit'] == 0) {
            $data = [
                &$this->info['section_name']
            ];
            $this->db->prepare_Stmt('insert into `tbl_product_sections`
                ( section_name) values (?)', $data);
        } else {
            $data = [
                &$this->info['section_name'],
                &$this->info['section_id']
            ];
            $this->db->prepare_Stmt('update `tbl_product_sections`
                set `section_name`=? where section_id =?', $data);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function delete_product_section($id) {
        $query = $this->db->query('select section_id from tbl_stock_products where section_id = "' . $id . '"');
        $count = $this->db->rowsno($query);
        if ($count > 0) {
            return [CommonLanguage::getMessage('product_section_used')];
        }
        $this->db->prepare_Stmt('delete from tbl_product_sections where section_id = ?', [&$id]);
        $error = $this->db->error();
        return $error;
    }

    public function check_product_property_used($prop_id) {
        $query = $this->db->query('SELECT schedule_repeat_id FROM tbl_checklist_schedule 
            WHERE schedule_type_id =2 and schedule_repeat_id = "' . $prop_id . '"');
        $count = $this->db->rowsno($query);
        if ($count > 0) {
            return true;
        }
        $query = $this->db->query('SELECT property_id FROM tbl_product_property_values_details
            WHERE property_id = "' . $prop_id . '"');
        $count = $this->db->rowsno($query);
        if ($count > 0) {
            return true;
        }
        return false;
    }

    public function check_product_part_used($part_id) {
        $query = $this->db->query('SELECT `part_id` FROM `tbl_checklist_schedule` 
            WHERE  part_id = "' . $part_id . '"');
        $count = $this->db->rowsno($query);
        if ($count > 0) {
            return true;
        }
        $query = $this->db->query('SELECT `part_product_id` 
            FROM `tbl_product_expense_details` WHERE `part_product_id` = "' . $part_id . '"');
        $count = $this->db->rowsno($query);
        if ($count > 0) {
            return true;
        }
        return false;
    }

    public function MachinePartSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( Product_Name LIKE ? or Product_Code LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        if (!empty($this->info['Status_ID'])) {
            $cond .= ' and Status_ID = 1 ';
        }
        if (!empty($this->info['is_edited'])) {
            $cond .= ' and (Status_ID = 1 or (Status_ID = 0 and Product_ID = ?) )';
            $data_filter[] = $this->info['is_edited'];
        }
        if (!empty($this->info['id'])) {
            $not_included = $this->info['id'];
            //            $direct_machine_parts = $this->db->query('select * from tbl_stock_products_parts
            //                                                    where Product_ID ="'.$this->info['id'].'"');
            //            while($direct_machine_row = $this->db->assoc($direct_machine_parts)){
            //                $not_included .= ','.$direct_machine_row['part_product_id'];
            //            }
            $cond .= ' and  Product_ID NOT IN (' . $not_included . ')';
        }

        $query = $this->db->prepare_Stmt('SELECT Product_ID as id,concat (Product_Name," - ",Product_Code) as text
            FROM tbl_stock_products where  machine_type_id ' . ($this->info['type'] == 'all' ? 'IN (1,2)' : ('= "' . $this->info['type'] . '"')) . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function MachineLineSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( products.Product_Name LIKE ? or products.Product_Code LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        //        if (!empty($this->info['Status_ID'])) {
        //            $cond .= ' and products.Status_ID = 1 ';
        //        }
        //        if (!empty($this->info['is_edited'])) {
        //            $cond .= ' and (products.Status_ID = 1 or (products.Status_ID = 0 and products.Product_ID = "' . $this->info['is_edited'] . '") )';
        //        }
        $line_machine = self::getLineMachines($this->info['line_id']);
        if (!empty($line_machine))
            $cond .= ' and parts.part_id IN (' . implode(",", $line_machine) . ') ';
        else
            $cond .= ' and parts.part_id = 0';
        $query = $this->db->prepare_Stmt('SELECT parts.part_id as id,
                                          concat_ws(" - ",products.Product_Name,products.Product_Code,parts.part_note) as text,
                                          products.Product_ID
                                  FROM tbl_stock_products_parts parts
                                  inner join tbl_stock_products products on products.Product_ID = parts.part_product_id
                                  where  products.machine_type_id = 1' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function MainMachineSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( products.Product_Name LIKE ? or products.Product_Code LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        if (!empty($this->info['Status_ID'])) {
            $cond .= ' and products.Status_ID = 1 ';
        }
        if (!empty($this->info['is_edited'])) {
            $cond .= ' and (Status_ID = 1 or (Status_ID = 0 and Product_ID = ? ) )';
            $data_filter[] = $this->info['is_edited'];
        }
        $query = $this->db->prepare_Stmt('SELECT products.Product_ID as id,
                                          concat_ws(" - ",products.Product_Name,products.Product_Code,product_parts.part_note) as text
                                  FROM tbl_stock_products_parts product_parts 
                                  inner join tbl_stock_products products on product_parts.part_product_id = products.Product_ID
                                  where  product_parts.Product_ID = 0 ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function ScheduleSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( schd.schedule_title LIKE ? or products.Product_Name LIKE ?  
                or product_machine.part_note LIKE ?  or part_machine.part_note  LIKE ? 
                or parts.Product_Name LIKE ? or line.line_name LIKE ?)';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        //        if (!empty($this->info['Status_ID'])) {
        //            $cond .= ' and p.Status_ID = 1 ';
        //        }
        //        if (!empty($this->info['is_edited'])) {
        //            $cond .= ' and (p.Status_ID = 1 or (p.Status_ID = 0 and products.Product_ID = "' . $this->info['is_edited'] . '") )';
        //        }

        $query = $this->db->prepare_Stmt('SELECT schd.schedule_id as id,
                                          concat_ws(" - ",schd.schedule_title,line.line_name,products.Product_Name,product_machine.part_note,parts.Product_Name,part_machine.part_note) as text
                                   FROM tbl_checklist_schedule schd 
                                   inner join tbl_line line using(line_id)
                                   inner join tbl_stock_products_parts product_machine on schd.Product_ID = product_machine.part_id
                                   inner join tbl_stock_products products on products.Product_ID = product_machine.part_product_id
                                   left join tbl_stock_products_parts part_machine on schd.part_id = part_machine.part_id
                                   left join tbl_stock_products parts on parts.Product_ID = part_machine.part_product_id
                                   where  1=1 ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function PartSearch($term = null, $page, $limit, $is_product) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $part_query = $this->db->query('select * from tbl_stock_products_parts where  part_id = "' . $this->info['Product_ID'] . '"');
        $this->info['Product_ID'] = $this->db->assoc($part_query)['part_product_id'];
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and (products.Product_Name LIKE ? or parts.part_note LIKE ? )';
            $data_filter[] = "%" . $term . "%";
            $data_filter[] = "%" . $term . "%";
        }
        $query = $this->db->prepare_Stmt('SELECT ' . ($is_product == 1 ? 'parts.part_product_id' : 'parts.part_id') . ' as id,
                                          concat_ws(" - ",products.Product_Name,parts.part_note) as text,
                                          products.is_service,parts.part_product_id
                                    FROM tbl_stock_products_parts parts
                                    inner join tbl_stock_products products on products.Product_ID = parts.part_product_id
                                    where  parts.Product_ID = "' . ($this->info['Product_ID'] ? $this->info['Product_ID'] : '0') . '" 
                                   /*and products.machine_type_id = 2*/' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function get_product_maintenance($id) {
        $data = array("prop" => array(), "parts" => array());
        $part_query = $this->db->query('select * from tbl_stock_products_parts where  part_id = "' . $id . '"');
        $id = $this->db->assoc($part_query)['part_product_id'];
        $query = $this->db->query('select * from tbl_stock_product_properties where Product_ID = "' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            $row['is_used'] = $this->check_product_property_used($row['property_id']);
            $data['prop'][] = $row;
        }
        $query = $this->db->query('select * from tbl_stock_products_parts p 
            join tbl_stock_products pr on p.part_product_id = pr.Product_ID
            where p.Product_ID = "' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            $row['is_used'] = $this->check_product_part_used($row['part_product_id']);
            $data['parts'][] = $row;
        }
        return $data;
    }

    public function PropertySearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $part_query = $this->db->query('select * from tbl_stock_products_parts where  part_id = "' . $this->info['Product_ID'] . '"');
        $this->info['Product_ID'] = $this->db->assoc($part_query)['part_product_id'];
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and property_name LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }

        $query = $this->db->prepare_Stmt('SELECT property_id as id,
                                          property_name as text
                                    FROM tbl_stock_product_properties 
                                    where  Product_ID = "' . $this->info['Product_ID'] . '" 
                                    ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function PropertyLineSearch($term = null, $page, $limit) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and property_name LIKE ? ';
            $data_filter[] = "%" . $term . "%";
        }

        $query = $this->db->prepare_Stmt('SELECT property_id as id,
                                          property_name as text
                                    FROM tbl_stock_product_properties 
                                    where  Product_ID = "' . $this->info['Product_ID'] . '" 
                                    ' . $cond . ' limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function add_edit_property_values() {
        $this->db->query('START TRANSACTION');
        $logged_id = smc_session()['user_logged_id'];
        $mydate = date('Y-m-d H:i:s');
        $property_values = array();
        if ($this->info['is_edit'] == 0) {
            $data = [&$this->info['line_id'], &$this->info['product_id'], &$this->info['value_date_time'],
                &$this->info['note'], &$logged_id, &$logged_id, &$mydate, &$mydate];
            $this->db->prepare_Stmt('insert into tbl_product_property_values (line_id,`Product_ID`, `value_date_time`,
            `note`, `Logged_ID`, `created_logged_id`, `date_created`, `date_time`) values(?,?,?,?,?,?,?,?)', $data);
            //       $error = $this->db->error();die(print_r($error));
            $value_id = $this->db->id();
            foreach ($this->info['properties'] as $prop) {
                $this->db->prepare_Stmt('insert into tbl_product_property_values_details 
                (property_id,property_value,value_id) values(?,?,?) ', [&$prop['property_id'], &$prop['property_value'], &$value_id]);
                $property_values[$prop['property_id']] = $prop['property_value'];
            }
            self::updateScheduleChecklistProperties($property_values, $this->info['value_date_time']);
        } else {
            $property_new = array();
            $property_values = self::getOldProperties($this->info['value_id']);
            $data = [&$this->info['line_id'], &$this->info['product_id'], &$this->info['value_date_time'],
                &$this->info['note'], &$logged_id, &$mydate, &$this->info['value_id']];
            $this->db->prepare_Stmt('update tbl_product_property_values set line_id =?,`Product_ID`=?, `value_date_time`=?,
            `note`=?, `Logged_ID`=? , `date_time`=? where value_id = ?', $data);
            $this->db->prepare_Stmt('delete from tbl_product_property_values_details where value_id = ?', [&$this->info['value_id']]);
            foreach ($this->info['properties'] as $prop) {
                $this->db->prepare_Stmt('insert into tbl_product_property_values_details 
                (property_id,property_value,value_id) values(?,?,?) ', [&$prop['property_id'], &$prop['property_value'], &$this->info['value_id']]);
                $property_values[$prop['property_id']]['new'] = $prop['property_value'];
                $property_new[$prop['property_id']] = $prop['property_value'];
            }
            self::updateScheduleChecklistAfterEditingProperties($property_values, $this->info['value_id']);
            self::updateScheduleChecklistProperties($property_new, $this->info['value_date_time']);
        }

        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function updateScheduleChecklistProperties($property, $datetime) {
        foreach ($property as $key => $value) {
            $schedule_query = $this->db->query('select * from tbl_checklist_schedule where schedule_repeat_id = "' . $key . '" and schedule_type_id = 2 and Product_ID = "' . $this->info['product_id'] . '" and line_id = "' . $this->info['line_id'] . '" ');
            while ($row = $this->db->assoc($schedule_query)) {
                $last_run_date = $row['schedule_start_date'];
                if (!is_null($row['last_run_date']))
                    $last_run_date = $row['last_run_date'];
                if ($datetime > $last_run_date) {
                    $this->db->prepare_Stmt('update tbl_checklist_schedule set last_run_date= ?,property_value= property_value + ? where schedule_id = ? ', [&$last_run_date, &$property[$row['schedule_repeat_id']], &$row['schedule_id']]);
                }
            }
        }
    }

    public function getOldProperties($value_id) {
        $property = array();
        $property_value_query = $this->db->query('select * from tbl_product_property_values_details where value_id= "' . $value_id . '"');
        while ($property_row = $this->db->assoc($property_value_query)) {
            $property[$property_row['property_id']]['old'] = $property_row['property_value'];
        }
        return $property;
    }

    public function updateScheduleChecklistAfterEditingProperties($property, $value_id) {
        $old_value_query = $this->db->query('select value_date_time from tbl_product_property_values where value_id="' . $value_id . '"');
        $old_date_time = $this->db->assoc($old_value_query)['value_date_time'];
        foreach ($property as $key => $value) {
            $schedule_query = $this->db->query('select * from tbl_checklist_schedule where schedule_repeat_id = "' . $key . '"  and schedule_type_id = 2 and Product_ID = "' . $this->info['product_id'] . '" and line_id="' . $this->info['line_id'] . '" ');
            while ($row = $this->db->assoc($schedule_query)) {
                $last_run_date = $row['schedule_start_date'];
                if (!is_null($row['last_run_date']))
                    $last_run_date = $row['last_run_date'];
                if ($old_date_time > $last_run_date) {
                    $difference = $property[$row['schedule_repeat_id']]['old'] - $property[$row['schedule_repeat_id']]['new'];
                    $this->db->prepare_Stmt('update tbl_checklist_schedule set last_run_date= ?,property_value= property_value - ? where schedule_id = ? ', [&$last_run_date, &$difference, &$row['schedule_id']]);
                }
            }
        }
    }

    public function get_property_value_by_id($id) {
        $data = array();
        $query = $this->db->query('select v.*,p.Product_Code,p.Product_Name,line.line_name,`machines_products`.`part_id`,
                                          concat_ws(" - ",`p`.`Product_Name`,`machines_products`.`part_note`) AS `product_full_name`
            from tbl_product_property_values v
            inner join tbl_line line on v.line_id = line.line_id
            inner join `tbl_stock_products_parts` `machines_products` on `v`.`Product_ID` = `machines_products`.`part_id` 
            inner join `tbl_stock_products` `p` on `machines_products`.`part_product_id` = `p`.`Product_ID`
            where value_id = "' . $id . '"');
        $data = $this->db->assoc($query);
        $query_det = $this->db->query('select p.*,if(isnull(d.property_id),0,d.property_value) as property_value from 
            tbl_stock_product_properties p inner join tbl_product_property_values_details d 
            on d.property_id = p.property_id and d.value_id = "' . $id . '"
           ');
        while ($row = $this->db->assoc($query_det)) {
            $data['details'][] = $row;
        }
        return $data;
    }

    public function add_product_expenses() {

        $this->db->query('START TRANSACTION');
        $depot_id = $this->info['Depot_ID'];
        $branch_id = CommonBusiness::getBranchByDepot($depot_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;
        $expense_nb = self::get_prod_exp_nb($prefix, $this->info['is_actual']);
        $logged_id = smc_session()['user_logged_id'];
        $mydate = date('Y-m-d H:i:s');
        $today = Date::getToday();
        $yearid = $this->info['is_actual'] ? $this->year_id_actual : $this->year_id;
        $data = [&$expense_nb, &$this->info['product_id'], &$this->info['value_date_time'],
            &$logged_id, &$logged_id, &$mydate, &$mydate, &$this->info['note'], &$prefix, &$depot_id,
            &$branch_id, &$yearid, &$this->info['is_actual'], &$this->info['line_id']];
        $this->db->prepare_Stmt('insert into  `tbl_product_expenses`( `expense_nb`, `Product_ID`,
            `expense_date_time`, `created_logged_id`, `Logged_ID`, `date_created`, `date_time`, `note`, `prefix`,
            `Depot_ID`, `branch_id`,current_year_id,is_actual,line_id) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)', $data);
        $expense_id = $this->db->id();
        if (!empty($this->info['parts'])) {
            foreach ($this->info['parts'] as $part) {
                $def_rate = Product::getConvertedQuantity($part['uom_id'], $part['qty'], $part['part_product_id']);
                $def_qty = $part['qty'] * $def_rate;
                $parts_data = [&$expense_id, &$part['part_product_id'], &$part['qty'], &$part['uom_id'],
                    &$def_qty, &$part['cost']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_expense_details`(`expense_id`,
                    `part_product_id`, `current_quantity`, `UOM_ID`, `default_quantity`, `cost`)
                    values(?,?,?,?,?,?)', $parts_data);
                $is_service = !empty($part['is_service']) ? $part['is_service'] : 0;
                $part['cost'] = $def_rate == 0 ? 0 : $part['cost'] / $def_rate;
                $costdata = [
                    "Product_ID" => $part['product_id'],
                    "Quantity" => $def_qty,
                    "Unit_Cost" => $part['cost'],
                    "Currency_ID" => smc_session()['local_currency'],
                    "date_time" => $mydate,
                    "current_rate" => '1',
                    "depot_id" => $depot_id,
                    "trans_date" => $today,
                    "current_quantity" => $part['qty'],
                    "uom_id" => $part['uom_id'],
                    "is_actual" => $this->info['is_actual'],
                    "expiry_date" => null,
                    "main_id" => $expense_id,
                    "is_service" => $is_service,
                    "main_nb" => $prefix . $expense_nb
                ];
                //                $unit_cost = 0;
                $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $part['product_id'] . '"');

                $count_row = $this->db->rowsno($link_query);
                if ($count_row == 0) {
                    $cost = CommonBusiness::updateLinkQuantities($costdata, "add_machine_maintenance", '-');
                    //                    $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'] * $def_qty;
                        $costdata["Quantity"] = $link_qty;
                        $costdata["current_quantity"] = $link['current_quantity'] * $def_qty;
                        $costdata["Product_ID"] = $link['sub_product_id'];
                        $costdata["uom_id"] = $link['UOM_ID'];
                        $cost = CommonBusiness::updateLinkQuantities($costdata, "add_machine_maintenance", $link['operation']);
                        //                        $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                    }
                }
            }
        }

        if (!empty($this->info['expenses'])) {
            $jv = JV::returnJV($this->info['is_actual']);
            $ref = 'exp.' . $prefix . $expense_nb;
            $date = explode(' ', $this->info['value_date_time'])[0];
            foreach ($this->info['expenses'] as $exp) {
                $rate = CurrencyFactory::getLastExRate($exp['currency_id']);
                $exp_data = [&$expense_id, &$exp['account_id'], &$exp['supplier_id'], &$exp['amount'], &$exp['currency_id'], &$rate, &$exp['job_id']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_expense_accounts`( `expense_id`,
                    `Account_ID`, `Supplier_ID`, `amount`, `Currency_ID`, `current_rate`,job_id)
                    value (?,?,?,?,?,?,?)', $exp_data);
                $supp_acc = Supplier::getSupplierAccount($exp['supplier_id']);
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref,
                    "Transaction_Account" => $supp_acc,
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $exp['amount'],
                    "Transaction_Date" => $date,
                    "Currency_ID" => $exp['currency_id'],
                    "Logged_ID" => $logged_id,
                    "Transaction_Description" => 'Machine Maintenance Expense',
                    "Current_Ex_Rate" => $rate,
                    "main_id" => $expense_id,
                    "main_type" => "mex",
                    "branch_id" => $branch_id,
                    "due_date" => $date,
                    "main_nb" => $expense_nb,
                    "job_id" => $exp['job_id']
                ];
                JV::addTransaction($data_trans, $this->info['is_actual']);
                $exp_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref,
                    "Transaction_Account" => $exp['account_id'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $exp['amount'],
                    "Transaction_Date" => $date,
                    "Currency_ID" => $exp['currency_id'],
                    "Logged_ID" => $logged_id,
                    "Transaction_Description" => 'Machine Maintenance Expense',
                    "Current_Ex_Rate" => $rate,
                    "main_id" => $expense_id,
                    "main_type" => "mex",
                    "branch_id" => $branch_id,
                    "due_date" => $date,
                    "main_nb" => $expense_nb,
                    "job_id" => $exp['job_id']
                ];
                JV::addTransaction($exp_trans, $this->info['is_actual']);
            }
        }

        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

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

        return $Invoice;
    }

    public function get_product_expense_by_id($id) {
        $data = array();
        $query = $this->db->query('SELECT e.*,p.Product_Code,p.Product_Name,
            concat(d.Depot_Code," - ",d.Depot_Name) as Depot_Name,e.line_id,line.line_name,
              concat_ws(" - ",`p`.`Product_Name`,`machines_products`.`part_note`) AS `product_full_name`
            FROM `tbl_product_expenses` e 
            join tbl_line line on line.line_id = e.line_id
            inner join `tbl_stock_products_parts` `machines_products` on `e`.`Product_ID` = `machines_products`.`part_id` 
            inner join `tbl_stock_products` `p` on `machines_products`.`part_product_id` = `p`.`Product_ID` 
            join tbl_stock_depot_warehouse d on d.Depot_ID = e.Depot_ID where e.expense_id = "' . $id . '"');
        $data['main'] = $this->db->assoc($query);
        $query_det = $this->db->query('SELECT d.*, p.Product_Code,p.Product_Name,u.UOM_Name,
        concat_ws(" - ",p.Product_Name,product_parts.part_note) as product_part_note,p.is_service,p.Product_ID
            FROM `tbl_product_expense_details` d
            inner join tbl_stock_products_parts product_parts on product_parts.part_id = d.`part_product_id`

            inner join tbl_stock_products p on p.Product_ID = product_parts.`part_product_id`
            inner join tbl_stock_uom u on u.UOM_ID = d.UOM_ID
            where d.expense_id = "' . $id . '"');
        $data['details'] = array();
        while ($row = $this->db->assoc($query_det)) {
            $data['details'][] = $row;
        }

        $query_exp = $this->db->query('SELECT a.*,s.Supplier_Name,c.Account_Name,c.Account_Code,
            cu.Currency_Name,j.job_name FROM `tbl_product_expense_accounts` a
            join tbl_stock_suppliers s on s.Supplier_ID = a.`Supplier_ID` 
            left join tbl_accounting_jobs j on j.job_id = a.`job_id` 
            join tbl_chart_of_accounts c 
            on c.Account_ID = a.`Account_ID` join tbl_common_currency cu on cu.Currency_ID = a.`Currency_ID` 
            where a.`expense_id` = "' . $id . '"');
        $data['expenses'] = array();
        while ($row_exp = $this->db->assoc($query_exp)) {
            $data['expenses'][] = $row_exp;
        }
        return $data;
    }

    public function edit_product_expenses($id) {
        $this->db->query('START TRANSACTION');
        $jv_query = $this->db->query("SELECT DISTINCT JV_ID,Current_Ex_Rate 
            FROM tbl_accounting_transactions  WHERE main_id='" . $id . "' AND main_type= 'mex' ");
        $jv_assoc = $this->db->assoc($jv_query);
        if (!empty($jv_assoc))
            $jv = $jv_assoc['JV_ID'];
        else
            $jv = JV::returnJV($this->info['is_actual']);
        $this->db->prepare_Stmt("DELETE FROM tbl_accounting_transactions  WHERE main_id= ?
             AND main_type= 'mex' ", [&$id]);

        $depot_id = $this->info['Depot_ID'];
        $branch_id = CommonBusiness::getBranchByDepot($depot_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;
        $logged_id = smc_session()['user_logged_id'];
        $mydate = date('Y-m-d H:i:s');
        $today = Date::getToday();
        $yearid = $this->info['is_actual'] ? $this->year_id_actual : $this->year_id;
        $data = [&$this->info['line_id'], &$this->info['product_id'], &$this->info['value_date_time'],
            &$logged_id, &$mydate, &$this->info['note'], &$depot_id,
            &$branch_id, &$id];
        $this->db->prepare_Stmt('update  `tbl_product_expenses` set line_id=?,`Product_ID`=?,
            `expense_date_time`=?, `Logged_ID`=?, `date_time`=?, `note`=?,
            `Depot_ID`=?, `branch_id`=? where expense_id = ?', $data);

        $expense_id = $id;
        $expense_nb = '';
        $expense_num = '';
        $old_date_time = $mydate;
        $old_created_logged_id = smc_session()['user_logged_id'];
        $old_date_created = $mydate;
        $query = $this->db->query("SELECT 
                                        if(isNull(l.link_id), parts.part_product_id, l.sub_product_id) as sub_product_id,
                                        if(isNull(l.link_id), p.current_quantity, (p.default_quantity * l.current_quantity)) as Current_Quantity,
                                        if(isNull(l.link_id), p.current_quantity, (p.default_quantity * l.quantity)) as Quantity,
                                        if(isNull(l.link_id), p.UOM_ID, l.UOM_ID) as UOM_ID,
                                        if(isNull(l.link_id), '-', l.operation) as operation,
                                        i.Depot_ID,
                                        i.date_time,
                                        if(isNull(l.link_id), 0, 1) as link_id,
                                        i.prefix,i.is_actual, 
                                        i.expense_nb,i.created_logged_id,i.date_created,p.cost,i.expense_date_time,pr.is_service
                                    FROM 
                                        tbl_product_expense_details p
                                    left JOIN
                                     tbl_stock_products_parts parts on parts.part_id = p.part_product_id
                                        left join tbl_products_link l
                                    on parts.part_product_id = l.main_product_id
                                    join tbl_product_expenses i on i.expense_id = p.expense_id
                                    join tbl_stock_products pr on pr.Product_ID = if(isNull(l.link_id), parts.part_product_id, l.sub_product_id)
                                    WHERE 
                                        p.expense_id = '" . $id . "'
                ");
        while ($row = $this->db->assoc($query)) {
            $date = explode(' ', $row['expense_date_time'])[0];
            $expense_nb = $row['expense_nb'];
            $expense_num = $row['prefix'] . $row['expense_nb'];
            $prefix = $row['prefix'];
            $old_created_logged_id = $row['created_logged_id'];
            $old_date_time = $row['date_time'];
            $old_date_created = $row['date_created'];
            $sub_cost = $row['link_id'] == 0 ? $row['cost'] : CommonBusiness::viewCurrentProductCost($row['sub_product_id']);
            $costdata = [
                "Product_ID" => $row['sub_product_id'],
                "Quantity" => $row['Quantity'],
                "Unit_Cost" => $sub_cost,
                "Currency_ID" => smc_session()['local_currency'],
                "date_time" => $row['date_time'],
                "current_rate" => 1,
                "depot_id" => $row['Depot_ID'],
                "trans_date" => $date,
                "current_quantity" => $row['Current_Quantity'],
                "uom_id" => $row['UOM_ID'],
                "is_actual" => $this->info['is_actual'],
                "expiry_date" => null,
                "main_id" => $id,
                "is_service" => $row['is_service'],
                "main_nb" => $expense_num
            ];

            CommonBusiness::updateLinkQuantities($costdata, "edit_machine_maintenance_old", ($row['operation'] == '+' ? '-' : '+'));
        }
        // $error = $this->db->error();
        //        die(print_r($error));

        $this->db->prepare_Stmt('delete from tbl_product_expense_details where expense_id = ?', [&$id]);
        if (!empty($this->info['parts'])) {
            CommonBusiness::update_trans_record_current('mch', $id);
            foreach ($this->info['parts'] as $part) {
                $def_qty = Product::getConvertedQuantity($part['uom_id'], $part['qty'], $part['part_product_id']);
                $parts_data = [&$expense_id, &$part['part_product_id'], &$part['qty'], &$part['uom_id'],
                    &$def_qty, &$part['cost']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_expense_details`(`expense_id`,
                    `part_product_id`, `current_quantity`, `UOM_ID`, `default_quantity`, `cost`)
                    values(?,?,?,?,?,?)', $parts_data);
                $is_service = !empty($part['is_service']) ? $part['is_service'] : 0;
                $costdata = [
                    "Product_ID" => $part['product_id'],
                    "Quantity" => $def_qty,
                    "Unit_Cost" => $part['cost'],
                    "Currency_ID" => smc_session()['local_currency'],
                    "date_time" => $mydate,
                    "current_rate" => '1',
                    "depot_id" => $depot_id,
                    "trans_date" => $today,
                    "current_quantity" => $part['qty'],
                    "uom_id" => $part['uom_id'],
                    "is_actual" => $this->info['is_actual'],
                    "expiry_date" => null,
                    "main_id" => $id,
                    "is_service" => $is_service,
                    "main_nb" => $expense_num
                ];
                //                $unit_cost = 0;
                $link_query = $this->db->query('select * from tbl_products_link where main_product_id = "' . $part['product_id'] . '"');

                $count_row = $this->db->rowsno($link_query);
                if ($count_row == 0) {
                    $cost = CommonBusiness::updateLinkQuantities($costdata, "edit_machine_maintenance_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'] * $def_qty;
                        $costdata["Quantity"] = $link_qty;
                        $costdata["current_quantity"] = $link['current_quantity'] * $def_qty;
                        $costdata["Product_ID"] = $link['sub_product_id'];
                        $costdata["uom_id"] = $link['UOM_ID'];
                        $cost = CommonBusiness::updateLinkQuantities($costdata, "edit_machine_maintenance_new", $link['operation']);
                        //                        $unit_cost += CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $this->info['Invoice_Currency'], $cost);
                    }
                }
            }
        }
        $this->db->prepare_Stmt('delete from tbl_product_expense_accounts where expense_id = ?', [&$id]);

        if (!empty($this->info['expenses'])) {
            $jv = JV::returnJV($this->info['is_actual']);
            $ref = 'exp.' . $prefix . $expense_nb;
            $date = explode(' ', $this->info['value_date_time'])[0];
            foreach ($this->info['expenses'] as $exp) {
                $rate = CurrencyFactory::getLastExRate($exp['currency_id']);
                $exp_data = [&$expense_id, &$exp['account_id'], &$exp['supplier_id'], &$exp['amount'], &$exp['currency_id'], &$rate, &$exp['job_id']];
                $this->db->prepare_Stmt('INSERT INTO `tbl_product_expense_accounts`( `expense_id`,
                    `Account_ID`, `Supplier_ID`, `amount`, `Currency_ID`, `current_rate`,job_id)
                    value (?,?,?,?,?,?,?)', $exp_data);
                $supp_acc = Supplier::getSupplierAccount($exp['supplier_id']);
                $data_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref,
                    "Transaction_Account" => $supp_acc,
                    "Transaction_Type" => "Credit",
                    "Transaction_Amount" => $exp['amount'],
                    "Transaction_Date" => $date,
                    "Currency_ID" => $exp['currency_id'],
                    "Logged_ID" => $logged_id,
                    "Transaction_Description" => 'Machine Maintenance Expense',
                    "Current_Ex_Rate" => $rate,
                    "main_id" => $expense_id,
                    "main_type" => "mex",
                    "branch_id" => $branch_id,
                    "due_date" => $date,
                    "main_nb" => $expense_nb,
                    "job_id" => $exp['job_id']
                ];
                JV::addTransaction($data_trans, $this->info['is_actual']);
                $exp_trans = ["JV_ID" => $jv,
                    "Transaction_Reference" => $ref,
                    "Transaction_Account" => $exp['account_id'],
                    "Transaction_Type" => "Debit",
                    "Transaction_Amount" => $exp['amount'],
                    "Transaction_Date" => $date,
                    "Currency_ID" => $exp['currency_id'],
                    "Logged_ID" => $logged_id,
                    "Transaction_Description" => 'Machine Maintenance Expense',
                    "Current_Ex_Rate" => $rate,
                    "main_id" => $expense_id,
                    "main_type" => "mex",
                    "branch_id" => $branch_id,
                    "due_date" => $date,
                    "main_nb" => $expense_nb,
                    "job_id" => $exp['job_id']
                ];
                JV::addTransaction($exp_trans, $this->info['is_actual']);
            }
        }

        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function total_product_expenses_report($date_from, $date_to, $currency_id = null, $section = null, $line_id = null) {
        $data = array();
        $prod_arr = array();
        $exp_ids_arr = array();
        $cond = ' ';
        $total = 0;
        if (!empty($section)) {
            $cond .= ' and section_id = "' . $section . '" ';
        }
        if (!empty($line_id)) {
            $cond .= ' and line_id = "' . $line_id . '" ';
        }
        if (empty($currency_id))
            $currency_id = smc_session()['local_currency'];
        $currency_symbol = CurrencyFactory::getCurrencySymbol($currency_id);

        $query = $this->db->query('select e.expense_id,p.Product_Code,concat_ws(" - ",`p`.`Product_Name`,`machines_products`.`part_note`) AS `product_full_name`,e.Product_ID

            from tbl_product_expenses e
            inner join `tbl_stock_products_parts` `machines_products` on `e`.`Product_ID` = `machines_products`.`part_id` 
            join tbl_stock_products p on p.Product_ID = machines_products.part_product_id
            where date(expense_date_time) between "' . $date_from . '" and "' . $date_to . '" ' . $cond);
        while ($row = $this->db->assoc($query)) {
            if (!array_key_exists($row['Product_ID'], $prod_arr)) {
                $row['total'] = 0;
                $row['currency_symbol'] = $currency_symbol;
                $prod_arr[$row['Product_ID']] = $row;
            }
            $exp_ids_arr[$row['expense_id']] = $row;
        }
        if (!empty($exp_ids_arr)) {
            $exp_ids_str = implode(',', array_keys($exp_ids_arr));
            $query_parts = $this->db->query('select sum(cost) as total_cost,e.Product_ID,date(expense_date_time) as exp_date
            from tbl_product_expense_details d
            join tbl_product_expenses e on e.expense_id = d.expense_id
            where d.expense_id in (' . $exp_ids_str . ') group by e.Product_ID');
            while ($row = $this->db->assoc($query_parts)) {
                $cost = ($currency_id != smc_session()['local_currency'] ? CurrencyFactory::convertCurrencyTimeExchangeRate(smc_session()['local_currency'], $currency_id, $row['total_cost'], $row['exp_date']) : $row['total_cost']);
                $prod_arr[$row['Product_ID']]['total'] += $cost;
                $total += $cost;
            }

            $query = $this->db->query('select sum(amount*current_rate) as total_cost,e.Product_ID,date(expense_date_time) as exp_date
            from tbl_product_expense_accounts d
            join tbl_product_expenses e on e.expense_id = d.expense_id
            where d.expense_id in (' . $exp_ids_str . ') group by e.Product_ID,d.Currency_ID');
            while ($row = $this->db->assoc($query)) {
                $cost = ($currency_id != smc_session()['local_currency'] ? CurrencyFactory::convertCurrencyTimeExchangeRate(smc_session()['local_currency'], $currency_id, $row['total_cost'], $row['exp_date']) : $row['total_cost']);
                $prod_arr[$row['Product_ID']]['total'] += $cost;
                $total += $cost;
            }
        }

        $data['details'] = $prod_arr;
        $data['total'] = CommonFunctions::formatNumber($total);
        $data['currency_symbol'] = $currency_symbol;
        $data_final = array_map(function($arr) {
            unset($arr['expense_id']);
            unset($arr['Product_ID']);
            $arr['total'] = CommonFunctions::formatNumber($arr['total']) . ' ' . $arr['currency_symbol'];
            unset($arr['currency_symbol']);
            return array_values($arr);
        }, $data['details']);
        $data['details'] = $data_final;
        return $data;
    }

    public function detail_product_expenses_report($date_from, $date_to, $machine_id = null, $currency_id = null, $line_id = null) {
        $data = array();
        $final_data = array();
        $cond = '';
        if (!empty($date_from) && !empty($date_to))
            $cond .= ' and date(e.expense_date_time) between "' . $date_from . '" and "' . $date_to . '"';
        if (!empty($machine_id))
            $cond .= ' and e.Product_ID = "' . $machine_id . '" ';
        if (!empty($line_id))
            $cond .= ' and e.line_id = "' . $line_id . '" ';
        if (empty($currency_id))
            $currency_id = smc_session()['local_currency'];
        $currency_symbol = CurrencyFactory::getCurrencySymbol($currency_id);
        $total = 0;
        $query = $this->db->query('select concat(c.Account_Code," - ",c.Account_Name) as name,"-" as qty,
            (amount*current_rate) as amount,
            date(expense_date_time) as exp_date,expense_date_time
            from tbl_product_expense_accounts d
            join tbl_product_expenses e on e.expense_id = d.expense_id
            join tbl_chart_of_accounts c on c.Account_ID = d.Account_ID
            where 1=1 ' . $cond);
        while ($row = $this->db->assoc($query)) {
            $amount = ($currency_id != smc_session()['local_currency'] ? CurrencyFactory::convertCurrencyTimeExchangeRate(smc_session()['local_currency'], $currency_id, $row['amount'], $row['exp_date']) : $row['amount']);
            $total += $amount;
            $row['amount'] = $amount . ' ' . $currency_symbol;
            unset($row['exp_date']);
            $data[] = array_values($row);
        }
        $query = $this->db->query('select concat(c.Product_Code," - ",c.Product_Name,part_product.part_note) as name,
            concat(d.current_quantity," ",u.UOM_Name) as qty,cost as amount,
            date(expense_date_time) as exp_date,expense_date_time
            from tbl_product_expense_details d
            join tbl_product_expenses e on e.expense_id = d.expense_id
            join tbl_stock_products_parts part_product on d.part_product_id = part_product.part_id
            join tbl_stock_products c on c.Product_ID = part_product.part_product_id
            join tbl_stock_uom u on u.UOM_ID = d.UOM_ID
            where 1=1 ' . $cond);
        while ($row = $this->db->assoc($query)) {
            $amount = ($currency_id != smc_session()['local_currency'] ? CurrencyFactory::convertCurrencyTimeExchangeRate(smc_session()['local_currency'], $currency_id, $row['amount'], $row['exp_date']) : $row['amount']);
            $total += $amount;
            $row['amount'] = $amount . ' ' . $currency_symbol;
            unset($row['exp_date']);
            $data[] = array_values($row);
        }
        $final_data['details'] = $data;
        $final_data['total'] = $total;
        $final_data['currency_symbol'] = $currency_symbol;
        return $final_data;
    }

    public function check_product_expiry($id) {
        $query = $this->db->query('select is_expiry,is_lot,is_serial from tbl_stock_products where Product_ID = "' . $id . '"');
        $row = $this->db->assoc($query);
        return $row;
    }

    public static function get_product_price($pid, $class_id, $uom_id = null, $with_currency = false) {
        $db = DBConnectorFactory::loadDriver();
        //$class_id=14;
        $query_class = $db->query('select pc.*,c.Currency_Symbol from tbl_pricing_class pc join tbl_common_currency c
            on pc.Currency_ID = c.Currency_ID where Class_ID = "' . $class_id . '"');
        $row = $db->assoc($query_class);
        $price = (is_array($pid) ? array() : 0 );
        if (!empty($pid)) {
            if (!is_array($pid)) {
                if ($row['is_virtual'] == 0) {
                    $query = $db->query('select pc.Product_Price from tbl_item_price_by_classes pc
					where pc.Class_ID = "' . $class_id . '" and pc.Product_ID = "' . $pid . '" and pc.UOM_ID = "' . $uom_id . '"');
                    $row_price = $db->assoc($query);
                    if (!empty($row_price))
                        $price = $row_price['Product_Price'];
                }else {
                    $query = $db->query('select a.type,a.sub_class_id,ifnull(pc.Product_Price,0) as Product_Price,a.percent,
						/*(pc.Product_Price+(pc.Product_Price*a.percent/100)) as Product_Price,*/c.Currency_ID 
						from tbl_pricing_class_alternatives a
					left join tbl_item_price_by_classes pc on pc.Class_ID = a.sub_class_id and pc.Product_ID = "' . $pid . '"
					and pc.UOM_ID = "' . $uom_id . '" and pc.Product_Price > 0
						left join tbl_pricing_class c on c.Class_ID = a.sub_class_id
					where a.main_class_id = "' . $class_id . '"  and pc.Product_Price > 0  order by a.entry_id asc limit 1');
                    $row_price = $db->assoc($query);
                    if (!empty($row_price)) {
                        if ($row_price['type'] == 0) {
                            $row_price['Product_Price'] = $row_price['Product_Price'];
                        } elseif ($row_price['type'] == 1 || $row_price['type'] == 2) {
                            $prod_arr[$pid] = $row_price;
                            $type = $row_price['type'] == 1 ? 'method' : 'last_cost';
                            $row_price['Product_Price'] = self::get_unit_cost_by_method($type, $row_price['sub_class_id'], $prod_arr)[$pid]['Price'];
                            $row_price['Currency_ID'] = smc_session()['local_currency'];
                        }
                        $row_price['Product_Price'] = ($row_price['Product_Price'] + ($row_price['Product_Price'] * $row_price['percent'] / 100));
                        $price = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row_price['Currency_ID'], $row['Currency_ID'], $row_price['Product_Price']);
                    }
                }
            } else {
                if ($row['is_virtual'] == 0) {
                    $query = $db->query('select pc.Product_Price,pc.Product_ID from tbl_item_price_by_classes pc
						join tbl_stock_products p on p.Product_ID = pc.Product_ID and p.UOM_ID = pc.UOM_ID
					where pc.Class_ID = "' . $class_id . '" and pc.Product_ID in (' . implode(',', array_keys($pid)) . ') ');
                    while ($row_price = $db->assoc($query)) {
                        $price[$row_price['Product_ID']]['Price'] = $row_price['Product_Price'];
                    }
                } else {
                    foreach ($pid as $pid => $row_prod) {
                        $query = $db->query('select a.type,a.sub_class_id,ifnull(pc.Product_Price,0) as Product_Price,a.percent,
						/*(pc.Product_Price+(pc.Product_Price*a.percent/100)) as Product_Price,*/c.Currency_ID 
						from tbl_pricing_class_alternatives a
					left join tbl_item_price_by_classes pc on pc.Class_ID = a.sub_class_id and pc.Product_ID = "' . $pid . '"
					and pc.UOM_ID = "' . $row_prod['UOM_ID'] . '" and pc.Product_Price > 0
						left join tbl_pricing_class c on c.Class_ID = a.sub_class_id
					where a.main_class_id = "' . $class_id . '" and pc.Product_Price > 0 order by a.entry_id asc limit 1');
                        $row_price = $db->assoc($query);
                        if (!empty($row_price)) {
                            if ($row_price['type'] == 0) {
                                $row_price['Product_Price'] = $row_price['Product_Price'];
                            } elseif ($row_price['type'] == 1 || $row_price['type'] == 2) {
                                $prod_arr[$pid] = $row_price;
                                $type = $row_price['type'] == 1 ? 'method' : 'last_cost';
                                $row_price['Product_Price'] = self::get_unit_cost_by_method($type, $row_price['sub_class_id'], $prod_arr)[$pid]['Price'];
                                $row_price['Currency_ID'] = smc_session()['local_currency'];
                            }
                            $row_price['Product_Price'] = ($row_price['Product_Price'] + ($row_price['Product_Price'] * $row_price['percent'] / 100));
                            $price[$pid]['Price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row_price['Currency_ID'], $row['Currency_ID'], $row_price['Product_Price']);
                        }
                    }


                    //                die('select a.type,a.sub_class_id,ifnull(pc.Product_Price,0) as Product_Price,a.percent,
                    //                   /* (pc.Product_Price+(pc.Product_Price*a.percent/100)) as Product_Price,*/
                    //                    c.Currency_ID,pc.Product_ID from tbl_pricing_class_alternatives a
                    //                left join tbl_item_price_by_classes pc on pc.Class_ID = a.sub_class_id 
                    //                and pc.Product_ID in (' . implode(',', array_keys($pid)) . ') and pc.Product_Price > 0
                    //                    left join tbl_stock_products p on p.Product_ID = pc.Product_ID and p.UOM_ID = pc.UOM_ID
                    //                    left join tbl_pricing_class c on c.Class_ID = a.sub_class_id
                    //                where a.main_class_id = "' . $class_id . '" order by a.entry_id asc limit 1');
                    //                while ($row_price = $db->assoc($query)) {
                    //                    //                if (!empty($row_price)) {
                    //                    $price[$row_price['Product_ID']]['Price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($row_price['Currency_ID'], $row['Currency_ID'], $row_price['Product_Price']);
                    //                    //                }
                    //                }
                }
            }
        }
        return (is_array($pid) ? $price : ($with_currency ? ($price . ' ' . (empty($row) ? '' : $row['Currency_Symbol'])) : $price));
    }

    public static function getTotalProductReorderPoint() {
        $db = DBConnectorFactory::loadDriver();
        $total = 0;
        $query = $db->query('select count(*) as total from tbl_stock_products where  Product_Quantity <= Product_Reorder_Point and Status_ID = 1 and Product_Reorder_Point IS NOT NULL');
        $total = $db->assoc($query)['total'];
        return $total;
    }

    public static function get_Un_Read_messages() {
        $db = DBConnectorFactory::loadDriver();
        $total = 0;
        $query = $db->query('SELECT count(*) as total FROM `messages` m where m.to_user = '.smc_session()['user_logged_id'].' and m.status =0');
        $total = $db->assoc($query)['total'];
        return $total;
    }

    public function viewProductDetails($ParentID) {
        $data = array();
        $Condition = '';
        //        echo $ParentID.'=====';
        $Condition = $ParentID == -1 ? '' : ' WHERE parts_machine.Product_ID = "' . $ParentID . '"';
        $query = $this->db->query('SELECT 
                                        parts_machine.*,
                                        products.Product_Name,
                                       products.machine_type_id
                                    from tbl_stock_products_parts parts_machine
                                    inner join tbl_stock_products products
                                    on parts_machine.part_product_id = products.Product_ID
                                  ' . $Condition
        );
        while ($row = $this->db->assoc($query)) {
            $row["Product_Name"] = ucwords($row["Product_Name"]);
            $data[] = $row;
        }

        return $data;
    }

    public function getMachinePropertyDetails() {
        $data = array('property' => array());
        $query = $this->db->query('select products.*,
                                          uom.UOM_Name,
                                          cat.Cat_Name,
                                          sections.section_name
                                   from tbl_stock_products products 
                                   inner join tbl_stock_uom uom using(UOM_ID)
                                   inner join tbl_product_cat cat on cat.Cat_ID = products.Category_ID
                                   inner join tbl_product_sections sections using(section_id)
                                   where products.Product_ID = "' . $this->info['product_id'] . '"
                                   ');
        $data['main'] = $this->db->assoc($query);
        $data['main']['part_note'] = '';
        $property_query = $this->db->query('select * from tbl_stock_product_properties where Product_ID ="' . $this->info['product_id'] . '"');
        while ($row = $this->db->assoc($property_query)) {
            $data['property'][] = $row;
        }
        if ($this->info['entry_id'] == 0) {
            $machine_part_query = $this->db->query('select * from tbl_stock_products_parts where Product_ID =0 and part_product_id ="' . $this->info['product_id'] . '" ');
        } else {
            $machine_part_query = $this->db->query('select * from tbl_stock_products_parts where part_id ="' . $this->info['entry_id'] . '"');
        }

        $data['main']['part_note'] = $this->db->assoc($machine_part_query)['part_note'];
        return $data;
    }

    public function submitUnlinkDeleteMachPart() {
        $type = $this->info['type'];
        $machine_part_id = $this->info['machine_part_id'];
        $this->db->query('START TRANSACTION');
        $parents_arr = array();
        $prod_arr = array();
        $current_related_prod = $machine_part_id;
        $this->get_machine_tree($machine_part_id, $parents_arr, $prod_arr);
        foreach ($prod_arr as $prod) {
            if (!empty($prod['part_product_id']))
                $current_related_prod .= "," . $prod['part_product_id'];
        }
        $product_exist = self::checkIfProductUOMUsed($machine_part_id, null);
        if ($product_exist)
            return ['unable_delete_product'];
        if ($type == 2) {
            $this->db->prepare_Stmt("delete from tbl_stock_products_parts where part_product_id in ({$current_related_prod}) ");
            $data = ['Product_ID' => $machine_part_id];
            $this->setData($data)->deleteProduct(true);
        }
        if ($type == 1) {
            $query = $this->db->query('SELECT * FROM `tbl_stock_products_parts` WHERE `part_product_id` = "' . $machine_part_id . '" and part_id <> "' . $this->info['auto_id'] . '"');
            $rows_count = $this->db->rowsno($query);
            if ($rows_count == 0) {
                $this->db->prepare_Stmt("delete from tbl_stock_products_parts where part_product_id in ({$current_related_prod}) ");
            }
            $this->db->prepare_Stmt("delete from tbl_stock_products_parts where part_id =? ", [&$this->info['auto_id']]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function submitLinkMachinePart() {
        $this->db->prepare_Stmt("insert into tbl_stock_products_parts (part_product_id,Product_ID,part_note) Values (?,?,?)", [&$this->info['machine_part_id'], &$this->info['current_link_id'], &$this->info['part_note']]);
        $error = $this->db->error();
        return $error;
    }

    public function getLineMachines($id) {
        $line_main_machines = array();
        $line_main_machines_query = $this->db->query('select * from tbl_line_machine where line_id ="' . $id . '"');
        while ($row = $this->db->assoc($line_main_machines_query)) {
            $line_main_machines[] = $row['Product_ID'];
        }
        $current_related_prod = '';
        foreach ($line_main_machines as $machine) {
            $parents_arr = array();
            $prod_arr = array();
            $entry_arr = array();
            $main_machine_part_arr = self::getMainMachineId($machine);
            if (!empty($main_machine_part_arr)) {
                $main_machine_part_ids = implode(",", $main_machine_part_arr);
                $current_related_prod .= ($current_related_prod != '' ? ',' : '') . $main_machine_part_ids;
            }
            $this->get_machine_tree($machine, $parents_arr, $prod_arr, $entry_arr);
            foreach ($entry_arr as $prod) {
                if (!empty($prod['part_id']))
                    $current_related_prod .= ($current_related_prod != '' ? ',' : '') . $prod['part_id'];
            }
        }
        $current_related_machines = !empty($current_related_prod) ? array_unique(explode(',', $current_related_prod)) : array();
        return $current_related_machines;
    }

    public function getMainMachineId($id) {
        $data = array();
        $query = $this->db->query('select part_id from tbl_stock_products_parts where part_product_id = "' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row['part_id'];
        }
        return $data;
    }

    public function get_machine_tree($parent_id, &$parents_arr, &$prod_arr, &$entry_arr = null) {
        $new_parent_ids = array();
        $query = $this->db->query("select Product_ID,part_product_id,part_id,part_note from tbl_stock_products_parts where Product_ID IN ({$parent_id})");
        while ($row = $this->db->assoc($query)) {
            $prod_arr[$row['part_product_id']] = $row;
            if (!isset($parents_arr[$row['Product_ID']]))
                $parents_arr[$row['Product_ID']] = array();
            $new_parent_ids[$row['part_product_id']] = $row['part_product_id'];
            $parents_arr[$row['Product_ID']][] = $row['part_product_id'];
            $entry_arr[] = $row;
        }
        if (!empty($new_parent_ids))
            self::get_machine_tree(implode(',', $new_parent_ids), $parents_arr, $prod_arr, $entry_arr);
    }

    public function submitLine() {
        $line_id = $this->info['line_id'];
        $this->db->query('START TRANSACTION');
        $logged_id = smc_session()['user_logged_id'];
        $current_date_time = date("Y-m-d H:i:s");
        $machine_ids = explode(",", $this->info['Product_ID']);
        if ($line_id == 0) {
            $this->db->prepare_Stmt("insert into tbl_line (line_name,created_by,date_created,modified_by,date_modified) Values (?,?,?,?,?)", [&$this->info['line_name'], &$logged_id, &$current_date_time, &$logged_id, &$current_date_time]);
            $line_id = $this->db->id();
        } else {
            $old_line_machines = $this->db->query('select * from tbl_line_machine where line_id = "' . $line_id . '" and Product_ID not in (' . $this->info['Product_ID'] . ')');
            while ($row = $this->db->assoc($old_line_machines)) {
                $line_product_used = self::checkIfLineProductUsed($line_id, $row['Product_ID']);
                if ($line_product_used)
                    return [CommonLanguage::getMessage('unable_delete_line_product')];
            }
            $this->db->prepare_Stmt("update tbl_line set line_name = ?,modified_by=?,date_modified = ? where line_id= ?", [&$this->info['line_name'], &$logged_id, &$current_date_time, &$line_id]);
            $this->db->prepare_Stmt("delete from tbl_line_machine where line_id = ?", [&$line_id]);
        }
        foreach ($machine_ids as $machine_id) {
            $this->db->prepare_Stmt("insert into tbl_line_machine (Product_ID,line_id) Values (?,?)", [&$machine_id, &$line_id]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function deleteLine() {
        $this->db->query('START TRANSACTION');
        $line_used = self::checkIfLineProductUsed($this->info['line_id']);
        if ($line_used)
            return ['unable_delete_line'];
        $this->db->prepare_Stmt("delete from tbl_line_machine where line_id = ?", [&$this->info['line_id']]);
        $this->db->prepare_Stmt("delete from tbl_line where line_id = ?", [&$this->info['line_id']]);
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function getLineData() {
        $data = array();
        $line_query = $this->db->query('select * from tbl_line where line_id= "' . $this->info['line_id'] . '"');
        $data['line'] = $this->db->assoc($line_query);
        $line_machine_query = $this->db->query('select line_machine.Product_ID  as id,
                                                       products.Product_Name as text
                                                from tbl_line_machine line_machine
                                                inner join  tbl_stock_products products using(Product_ID)
                                                where line_machine.line_id = "' . $this->info['line_id'] . '"');
        while ($row = $this->db->assoc($line_machine_query)) {
            $data['line_machine'][] = $row;
        }
        return $data;
    }

    public function checkIfLineProductUsed($line_id, $pid = null) {
        //check if if line is used in expense
        $expense_query = $this->db->query('select * from tbl_product_expenses where line_id = "' . $line_id . '" ' . (!is_null($pid) ? ' and Product_ID = "' . $pid . '"' : '' ) . ' limit 1');
        $expense_count = $this->db->rowsno($expense_query);
        if ($expense_count > 0) {
            return true;
        }
        //check if if line is used in checklist schedule 
        $checklist_schedule_query = $this->db->query('select * from tbl_checklist_schedule where line_id = "' . $line_id . '" ' . (!is_null($pid) ? '  and Product_ID = "' . $pid . '" ' : '' ) . ' limit 1');
        $checklist_schedule_count = $this->db->rowsno($checklist_schedule_query);
        if ($checklist_schedule_count > 0) {
            return true;
        }
        //check if if line is used in checklist schedule 
        $property_query = $this->db->query('select * from tbl_product_property_values where line_id = "' . $line_id . '" ' . (!is_null($pid) ? '  and Product_ID = "' . $pid . '" ' : '' ) . ' limit 1');
        $property_count = $this->db->rowsno($property_query);
        if ($property_count > 0) {
            return true;
        }
        return false;
    }

    public function check_if_default_uom() {
        $data = array();
        $query = $this->db->query('select * from tbl_stock_uom');
        $row_no = $this->db->rowsno($query);
        if ($row_no == 1)
            $data = $this->db->assoc($query);
        return $data;
    }

    
    public function getProductRecipe() {
        $data = array('product_out' => array(), 'link_note' => '');
        $product_query = $this->db->query('select link_note from tbl_stock_products where Product_ID = "' . $this->info['product_id'] . '"');
        $data['link_note'] = $this->db->assoc($product_query)['link_note'];
        $query = $this->db->query('select * from product_link where main_product_id = "' . $this->info['product_id'] . '" and operation = "-"');
        while ($row = $this->db->assoc($query)) {
            $data['product_out'][] = $row;
        }
        return $data;
    }

    public function getLineMachineParts() {
        $data = array();
        $all_lines = CommonFunctions::CommonView('tbl_line');
        $lines = array();
        foreach ($all_lines as $line) {
            $lines[$line['line_id']] = $line;
            $lines[$line['line_id']]['lines_part_id'] = self::getLineMachines($line['line_id']);
        }
        $query = $this->db->query('select parts.*,
                                          parts.part_id as main_part_id,
                                          main_prod.machine_type_id as main_part_type_id,
                                          concat_ws(" - ",main_prod.Product_Name,parts.part_note)as main_product_name 
                                   from tbl_stock_products_parts parts
                                   inner join tbl_stock_products main_prod on  main_prod.Product_ID = parts.part_product_id
                                   where part_product_id ="' . $this->info['product_id'] . '"');
        while ($row = $this->db->assoc($query)) {
            $parent_data = self::getParentLineMachineData($row['Product_ID']);
            $current_lines = self::searchForPartInLine($lines, $row['part_id']);
            foreach ($current_lines as $line) {
                $row['line_id'] = $line;
                $row['line_name'] = $lines[$line]['line_name'];
                $row['parent_part_id'] = $parent_data['parent_part_id'];
                $row['parent_product_name'] = $parent_data['parent_product_name'];
                $row['parent_part_type_id'] = $parent_data['parent_part_type_id'];
                $data[] = $row;
            }
        }
        return $data;
    }

    public function searchForPartInLine($lines, $part_id) {
        $lines_exist = array();
        foreach ($lines as $line) {
            if (in_array($part_id, $line['lines_part_id']))
                $lines_exist[] = $line['line_id'];
        }
        return $lines_exist;
    }

    public function getParentLineMachineData($id) {
        $row = array();
        $query = $this->db->query('select parts.*,
                                          parts.part_id as parent_part_id,
                                          main_prod.machine_type_id as parent_part_type_id,
                                          concat_ws(" - ",main_prod.Product_Name,parts.part_note)as parent_product_name 
                                   from tbl_stock_products_parts parts
                                   inner join tbl_stock_products main_prod on  main_prod.Product_ID = parts.part_product_id
                                   where part_product_id ="' . $id . '"');
        $row = $this->db->assoc($query);
        return $row;
    }

    public function getTotalCostProductRecipe() {
        $current_cost = $total_cost = 0.0;
        $cond = ' ';
        if (!empty($this->info['product_id']))
            $cond .= ' and `main_product_id` = "' . $this->info['product_id'] . '" ';
        $query = $this->db->query('select sub_product_id,quantity  from tbl_products_link where operation = "-" ' . $cond);
        while ($row = $this->db->assoc($query)) {
            $current_cost = CommonBusiness::viewLastProductCost($row['sub_product_id']);
            $total_cost += $current_cost * $row['quantity'];
        }
        return CommonFunctions::formatNumber($total_cost);
    }

    public static function get_product_expiries($prod_ids) {
        $db = DBConnectorFactory::loadDriver();
        $data = array();
        $query = $db->query('select t.Product_ID,
            sum(if(Operation_Type="+",t.Product_Quantity,t.Product_Quantity*-1)/p.default_view_rate) as quantity,t.expiry_date 
            from tbl_stock_product_transactions t join tbl_stock_products p on p.Product_ID = t.Product_ID
            where t.Product_ID in (' . $prod_ids . ') 
                group by t.Product_ID,t.expiry_date having quantity > 0 order by expiry_date desc');
        while ($row = $db->assoc($query)) {
            $row['expiry_text'] = $row['expiry_date'] . ' - ' . $row['quantity'];
            $data[$row['Product_ID']] = $row;
        }
        return $data;
    }

    public function get_product_expiry($term = null, $page, $limit, $depot_id = null) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( t.expiry_date LIKE ? )';
            $data_filter[] = "%" . $term . "%";
        }
        if (!is_null($depot_id)) {
            $cond .= ' and t.Depot_ID = ?';
            $data_filter[] = $depot_id;
        }
        $query = $this->db->prepare_Stmt('select 
            sum(if(t.Operation_Type="+",t.Product_Quantity,t.Product_Quantity*-1)/p.default_view_rate) as text,
            t.expiry_date as id ,u.UOM_Name
            from tbl_stock_product_transactions t
            inner join tbl_stock_products p on p.Product_ID = t.Product_ID
            inner join tbl_stock_uom u on u.UOM_ID = p.default_view_uom_id
            where t.Product_ID = "' . $this->info['product_id'] . '"
                    ' . $cond . '
                group by t.expiry_date having text > 0  limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $row['text'] = $row['id'] . ' : ' . CommonFunctions::formatNumber($row['text']) . ' ' . $row['UOM_Name'];
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function get_product_serial($term = null, $page, $limit, $depot_id = null) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( t.serial_nb LIKE ? )';
            $data_filter[] = "%" . $term . "%";
        }
        if (!is_null($depot_id)) {
            $cond .= ' and t.Depot_ID = ?';
            $data_filter[] = $depot_id;
        }
        $query = $this->db->prepare_Stmt('select 
            sum(if(t.Operation_Type="+",t.Product_Quantity,t.Product_Quantity*-1)/p.default_view_rate) as text,
            t.serial_nb as id ,u.UOM_Name
            from tbl_stock_product_transactions t
            inner join tbl_stock_products p on p.Product_ID = t.Product_ID
            inner join tbl_stock_uom u on u.UOM_ID = p.default_view_uom_id
            where t.Product_ID = "' . $this->info['product_id'] . '"
                    ' . $cond . '
                group by t.serial_nb having text > 0  limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $row['text'] = $row['id'] . ' : ' . CommonFunctions::formatNumber($row['text']) . ' ' . $row['UOM_Name'];
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public function get_product_lot($term = null, $page, $limit, $depot_id = null) {
        $data = array();
        $data['is_more'] = false;
        $data['data'] = array();
        $cond = '';
        $data_filter = array();
        if (!is_null($term)) {
            $cond .= ' and ( t.lot_nb LIKE ? )';
            $data_filter[] = "%" . $term . "%";
        }
        if (!is_null($depot_id)) {
            $cond .= ' and t.Depot_ID = ?';
            $data_filter[] = $depot_id;
        }
        $query = $this->db->prepare_Stmt('select 
            sum(if(t.Operation_Type="+",t.Product_Quantity,t.Product_Quantity*-1)/p.default_view_rate) as text,
            lot_nb as id ,u.UOM_Name
            from tbl_stock_product_transactions t
            inner join tbl_stock_products p on p.Product_ID = t.Product_ID
            inner join tbl_stock_uom u on u.UOM_ID = p.default_view_uom_id
            where t.Product_ID = "' . $this->info['product_id'] . '"
                ' . $cond . '
                group by t.lot_nb having text > 0  limit ' . ($page * $limit) . ',' . ($limit + 1), $data_filter);
        while ($row = $this->db->assoc($query)) {
            $row['text'] = $row['id'] . ' : ' . CommonFunctions::formatNumber($row['text']) . ' ' . $row['UOM_Name'];
            $data['data'][] = $row;
        }
        if (count($data['data']) > $limit) {
            array_pop($data['data']);
            $data['is_more'] = true;
        }
        return $data;
    }

    public static function get_product_default_uom($product_id, $with_uom_name = false) {
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query('select p.UOM_ID,u.UOM_Name from tbl_stock_products p 
            join tbl_stock_uom u on u.UOM_ID = p.UOM_ID
            where Product_ID = "' . $product_id . '"');

        $row = $db->assoc($query);
        if (!$with_uom_name) {
            $uom_id = $row['UOM_ID'];
            return $uom_id;
        } else {
            return $row;
        }
    }
    public static function get_category_prefix_barcode($Cat_ID) {
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query('select * from tbl_product_cat where Cat_ID = "' . $Cat_ID . '"');
        $row = $db->assoc($query);
        
        $category_prefix_barcode = $row['category_prefix_barcode'];
        if($category_prefix_barcode){
            $not_found_barcode = true;
            while($not_found_barcode){
                $digits = 13 - strlen($row['category_prefix_barcode']);
                $new_barcode = $category_prefix_barcode .strval( rand(pow(10, $digits-1), pow(10, $digits)-1));
                $query_product = $db->query('select * from tbl_stock_products where Product_PLU = "' . $new_barcode . '"');
                $row_product = $db->assoc($query_product);
                if(empty($row_product)){
                    $not_found_barcode = false;
                }
            }
            $row['new_barcode'] = $new_barcode;
            return $row;
         }
         return '';
        }

    public function get_prod_default_price($pid) {
        $class = smc_session()['pricing_class_id'];
        $price = 0;
        $uom_id = self::get_product_default_uom($pid);
        if (empty($this->info['bone_date']))
            $price = self::get_product_price($pid, $class, $uom_id);
        else {
            //we put below date condition less than or equal so if he change it today to take in consideration new price
            $query = $this->db->query('select * from tbl_item_price_by_classes_log
                where  Product_ID ="' . $pid . '" and Class_ID = "' . $class . '" 
                    and UOM_ID = "' . $uom_id . '" and date(date_time) <= "' . $this->info['bone_date'] . '"  
                        order by date_time desc limit 1');
            $row = $this->db->assoc($query);
            $price = !empty($row['Product_Price']) ? $row['Product_Price'] : self::get_product_price($pid, $class, $uom_id);
        }
        return $price;
    }

    public function get_product_by_id($pid, $cid = null) {
        $data = array();
        $query = $this->db->query('select * from tbl_stock_products where Product_ID = "' . $pid . '"');
        $data = $this->db->assoc($query);
        $data['price'] = $this->get_prod_default_price($pid);
        $data['service_price'] = 0;
        if (!empty($cid)) {
            $data['service_price'] = $this->get_product_coupon_service($pid, $cid);
        }
        return $data;
    }

    public function get_product_coupon_service($pid, $cid) {
        $service_price = 0;
        $query = $this->db->query('select service_price from tbl_bone_type_services where product_id = "' . $pid . '"
            and bone_type_id ="' . $cid . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $service_price = $row['service_price'];
        return $service_price;
    }

    public function getProductReservationDuration() {
        $data = array();
        $query = $this->db->query('select  details.*,
        details.reserve_from as start,
        details.reserve_to  as end,
        concat_ws(" ",products.Product_Name,customer.Customer_Name) as description,
        details.Product_ID resources,
                                           concat_ws(" - ",products.Product_Name,customer.Customer_Name) as title
                                  from  tbl_invoice_products_details details
                                  inner join tbl_invoices invoices on details.Invoice_ID_Auto = invoices.Invoice_ID_Auto
                                  inner join tbl_customers customer on invoices.Customer_ID = customer.Customer_ID
                                  inner join tbl_stock_products products on products.Product_ID = details.Product_ID
                                where  
                                (details.reserve_from between  "' . $this->info['start'] . '" and "' . $this->info['end'] . '" or
                                details.reserve_to between "' . $this->info['start'] . '" and "' . $this->info['end'] . '")
                                and details.reserve_from IS NOT NULL
                                and details.reserve_from <> "0000-00-00 00:00:00"
                                and details.reserve_to IS NOT NULL
                                and details.reserve_to <> "0000-00-00 00:00:00"
                                  Order by  details.reserve_from desc  ');
        while ($row = $this->db->assoc($query)) {
            $row['start'] = date('Y-m-d\TH:i:s\Z', strtotime($row['start']));
            $row['end'] = date('Y-m-d\TH:i:s\Z', strtotime($row['end']));
            $data[] = $row;
        }
        return $data;
    }

    public function getProductResources() {
        $data = array();
        $query = $this->db->query('SELECT 
                                    Product_ID as id,
                                    Product_Name as name
                                FROM 
                                    tbl_stock_products
                                where duration_reservation= 1

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

    public function submitProductNote() {
        $note_id = $this->info['note_id'];
        if ($note_id == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_product_note
                                     (note_title,is_linked)
                                     VALUES
                                    (?,?)
                                         ', [&$this->info['note_title'], &$this->info['is_linked']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_product_note
                                                 SET
                                                        note_title = ?,
                                                        is_linked = ?
                                                 WHERE 
                                                        note_id =?

                                         ', [&$this->info['note_title'], &$this->info['is_linked'], &$note_id]);
        }
        $error = $this->db->error();
        return $error;
    }

    public function submitPrinter() {
        $printer_id = $this->info['printer_id'];
        if ($printer_id == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_printers
                                     (printer_name,printer_title,printer_key,is_default,branch_id)
                                     VALUES
                                    (?,?,?,?,?)
                                         ', [&$this->info['printer_name'], &$this->info['printer_title'],
                &$this->info['printer_key'], &$this->info['is_default'],
                &$this->info['branch_id']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_printers
                                                 SET
                                                        printer_name = ?,
                                                        printer_title = ?,
                                                        printer_key = ?,
                                                        is_default = ?,
                                                        branch_id = ?
                                                 WHERE 
                                                        printer_id =?

                                         ', [&$this->info['printer_name'], &$this->info['printer_title'],
                &$this->info['printer_key'],
                &$this->info['is_default'], &$this->info['branch_id'], &$printer_id]);
        }
        $error = $this->db->error();
        return $error;
    }

    public function submitFamily() {
        $family_id = $this->info['family_id'];
        if ($family_id == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_inventory_family
                                     (family_name)
                                     VALUES
                                    (?)
                                         ', [&$this->info['family_name']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_inventory_family
                                                 SET
                                                        family_name = ?
                                                 WHERE 
                                                        family_id =?

                                         ', [&$this->info['family_name'], &$family_id]);
        }
        $error = $this->db->error();
        return $error;
    }

    public function deleteFamily($family_id) {
        $query = $this->db->query('select * from tbl_stock_products where  family_id = "' . $family_id . '"');
        $family_linked_product_count = $this->db->rowsno($query);
        if ($family_linked_product_count > 0) {
            return [CommonLanguage::getMessage('family_linked_product')];
        }

        $this->db->prepare_Stmt('delete from tbl_inventory_family where family_id = ?', [&$family_id]);
        $error = $this->db->error();
        return $error;
    }

    public function deleteProductNote() {
        $this->db->prepare_Stmt('Delete from tbl_product_note WHERE note_id =? ', [&$this->info['entry_value']]);
        $error = $this->db->error();
        return $error;
    }

    public function submitMultiProductEdit() {
        $this->db->query('START TRANSACTION');
        $product_options = $this->info['product_options'];
        $product_data = '';
        if (in_array(1, $product_options)) {
            $product_data .= ' branch_id =?';
        }
        if (in_array(2, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' printer_id =?';
        }
        if (in_array(3, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' Product_Limit_Discount =?';
        }
        if (in_array(4, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' family_id =?';
        }
        if (in_array(5, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' Category_ID =?';
        }
        if (in_array(6, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' Status_ID = ?';
        }
        if (in_array(7, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' brand_id = ?';
        }
        if (in_array(8, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' vat_percent = ?';
        }
        if (in_array(9, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' vat2_percent = ?';
        }
        if (in_array(10, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' Product_Reorder_Point = ?';
        }
        if (in_array(11, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' positive_points = ?';
        }
        if (in_array(12, $product_options)) {
            $product_data .= ($product_data == '' ? '' : ',') . ' negative_points = ?';
        }

        foreach ($this->info['products'] as $product) {
            $product_arr = [];
            $product['branch_id'] = !empty($product['branch_id']) ? implode(',', $product['branch_id']) : NULL;
            $product['printer_id'] = !empty($product['printer_id']) ? implode(',', $product['printer_id']) : NULL;
            $product['Product_Limit_Discount'] = !empty($product['Product_Limit_Discount']) ? $product['Product_Limit_Discount'] : NULL;
            $product['family_id'] = !empty($product['family_id']) ? $product['family_id'] : NULL;
            $product['category_id'] = !empty($product['category_id']) ? $product['category_id'] : NULL;
            $product['vat_percent'] = !empty($product['vat_percent']) ? $product['vat_percent'] : 0;
            $product['vat2_percent'] = !empty($product['vat2_percent']) ? $product['vat2_percent'] : 0;
            $product['Product_Reorder_Point'] = !empty($product['Product_Reorder_Point']) ? $product['Product_Reorder_Point'] : NULL;
            $product['positive_points'] = !empty($product['positive_points']) ? $product['positive_points'] : 0;
            $product['negative_points'] = !empty($product['negative_points']) ? $product['negative_points'] : 0;
            if (in_array(1, $product_options))
                $product_arr[] = &$product['branch_id'];
            if (in_array(2, $product_options))
                $product_arr[] = &$product['printer_id'];
            if (in_array(3, $product_options))
                $product_arr[] = &$product['Product_Limit_Discount'];
            if (in_array(4, $product_options))
                $product_arr[] = &$product['family_id'];
            if (in_array(5, $product_options))
                $product_arr[] = &$product['category_id'];
            if (in_array(6, $product_options))
                $product_arr[] = &$product['Status_ID'];
            if (in_array(7, $product_options))
                $product_arr[] = &$product['brand_id'];
            if (in_array(8, $product_options))
                $product_arr[] = &$product['vat_percent'];
            if (in_array(9, $product_options))
                $product_arr[] = &$product['vat2_percent'];
            if (in_array(10, $product_options))
                $product_arr[] = &$product['Product_Reorder_Point'];
            if (in_array(11, $product_options))
                $product_arr[] = &$product['positive_points'];
            if (in_array(12, $product_options))
                $product_arr[] = &$product['negative_points'];
            $product_arr[] = &$product['product_id'];
            $this->db->prepare_Stmt('update  tbl_stock_products  set ' . $product_data . ' WHERE Product_ID =? ', $product_arr);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public static function check_product_branches($branch_id, $prod_ids) {
        $data = array();
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query("SELECT * FROM `tbl_stock_products` 
            WHERE concat(',',`branch_id`,',') not like ('%," . $branch_id . ",%') 
            and Product_ID in (" . $prod_ids . ")");
        while ($row = $db->assoc($query)) {
            $data[] = $row['Product_ID'];
        }
        return $data;
    }

    public function getAllPrinters() {
        $data = array();
        $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 * from tbl_printers where  (branch_id = "" or concat_ws("",",",branch_id,",") LIKE  "%,' . $branch_id . ',%")');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function deletePrinter($printer_id) {
        $query = $this->db->query('select * from tbl_stock_products where  concat_ws("",",",printer_id,",") LIKE  "%,' . $printer_id . ',%"');
        $printer_linked_product_count = $this->db->rowsno($query);
        if ($printer_linked_product_count > 0) {
            return [CommonLanguage::getMessage('printer_linked_product')];
        }

        $this->db->prepare_Stmt('delete from tbl_printers where printer_id = ?', [&$printer_id]);
        $error = $this->db->error();
        return $error;
    }

    public function deleteProductSpecificationOptions() {
        $this->db->prepare_Stmt('delete from tbl_product_specification where product_specification_id = ?', [&$this->info['product_specification_id']]);
        $error = $this->db->error();
        return $error;
    }

    public function submitProductSpecificationOptions() {
        $this->db->query('START TRANSACTION');
        $product_specification_id = $this->info['product_specification_id'];
        if ($product_specification_id == 0) {
            $this->db->prepare_Stmt('insert into tbl_product_specification 
            (product_specification_name)VALUES(?) ', [&$this->info['product_specification_name']]);
            $product_specification_id = $this->db->id();
        } else {
            $this->db->prepare_Stmt('update  tbl_product_specification  set product_specification_name =? WHERE product_specification_id =? ', [&$this->info['product_specification_name'], &$product_specification_id]);
            $this->db->prepare_Stmt('delete from  tbl_product_specification_option   WHERE product_specification_id =? ', [&$product_specification_id]);
        }
        $options = json_decode($this->info['option'], true);
        foreach ($options as $option) {
            $this->db->prepare_Stmt('insert into tbl_product_specification_option 
            (option_name,option_code,product_specification_id)VALUES(?,?,?) ', [&$option['name'], &$option['code'], &$product_specification_id]);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function viewProductSpecificationOptions($product_specification_id) {
        $data = array();
        $specification_query = $this->db->query('select * from tbl_product_specification where product_specification_id = "' . $product_specification_id . '"');
        $data['main'] = $this->db->assoc($specification_query);
        $options_query = $this->db->query('select * from tbl_product_specification_option where product_specification_id = "' . $product_specification_id . '"');
        while ($row = $this->db->assoc($options_query)) {
            $data['options'][] = $row;
        }
        return $data;
    }

    public function get_item_prices($item_ids, $id, $is_purchase, $adj_class_id) {
        $data = array();
        $query_cur = $this->db->query('select Currency_ID from tbl_pricing_class where Class_ID = "' . $adj_class_id . '"');
        $currency_id = $this->db->assoc($query_cur)['Currency_ID'];
        if ($is_purchase == 0) {
            $query_cur = $this->db->query('select Currency_ID from tbl_pricing_class 
                 where Class_ID = "' . $id . '"');
            $from_currency_id = $this->db->assoc($query_cur)['Currency_ID'];
            $query = $this->db->query('select u.Product_ID,ifnull(pc.Product_Price,0) as Product_Price,
            u.uom_from as UOM_ID 
            from tbl_uom_conversions u left join  tbl_item_price_by_classes pc
            on pc.Product_ID = u.Product_ID and u.uom_from = pc.UOM_ID and pc.Class_ID = "' . $id . '"
            where u.Product_ID in (' . (implode(',', $item_ids)) . ')');
            while ($row = $this->db->assoc($query)) {
                $row['Product_Price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($from_currency_id, $currency_id, $row['Product_Price']);
                $data[] = $row;
            }
        } else {
            $query_cur = $this->db->query('select Currency_ID from tbl_inventory_purchases 
                 where Purchase_ID_Auto = "' . $id . '"');
            $from_currency_id = $this->db->assoc($query_cur)['Currency_ID'];
            $query = $this->db->query('select u.Product_ID,ifnull(pc.Item_Price,0) as Product_Price,
            u.uom_from as UOM_ID 
            from tbl_uom_conversions u left join tbl_inventory_purchase_items pc
            on pc.Product_ID = u.Product_ID and u.uom_from = pc.UOM_ID
            and pc.Purchase_ID_Auto = "' . $id . '"
            where u.Product_ID in (' . (implode(',', $item_ids)) . ')');
            while ($row = $this->db->assoc($query)) {
                $row['Product_Price'] = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies($from_currency_id, $currency_id, $row['Product_Price']);
                $data[] = $row;
            }
        }
        return $data;
    }

    public function get_item_by_last_cost($item_ids, $id) {
        $data = array();
        $query_cur = $this->db->query('select Currency_ID from tbl_pricing_class  where Class_ID = "' . $id . '"');
        $to_currency_id = $this->db->assoc($query_cur)['Currency_ID'];
        $query = $this->db->query('select u.Product_ID,
            u.uom_from as UOM_ID 
            from tbl_uom_conversions u left join  tbl_stock_products pc
            on pc.Product_ID = u.Product_ID and u.uom_from = pc.UOM_ID 
            where u.Product_ID in (' . (implode(',', $item_ids)) . ')');
        while ($row = $this->db->assoc($query)) {
            $Unit_Cost = CommonBusiness::viewLastProductCost($row['Product_ID']);
            $Unit_Cost = CurrencyFactory::returnExchangedValueBetweenTwoCurrencies(smc_session()['local_currency'], $to_currency_id, $Unit_Cost);
            $data[] = ['Product_ID' => $row['Product_ID'], 'Product_Price' => $Unit_Cost, 'UOM_ID' => $row['UOM_ID']];
        }
        return $data;
    }

    //    public function product_recipe_report(){
    ////        product_link
    //        $data = array();
    //        $prod_arr = array();
    //        $query = "select concat(cc.`main_product_id`,'',1) AS `mykey`,
    //            `cc`.`main_product_id` AS `id`,cc.Product_Name
    //                    from `product_link` cc union select concat(`sc`.`main_product_id`,'',1) AS `mykey`,
    //                        `sc`.`main_product_id` AS `id`,`sc`.`Product_Name`
    //                        from (`product_link` `sc` ) 
    //                       ";
    //        $query = $this->db->query('select distinct main_product_id ,p.Product_Code,p.Product_Name
    //            from tbl_products_link l join tbl_stock_products p on p.Product_ID = l.main_product_id ');
    //        while($row = $this->db->assoc($query)){
    //            $prod_arr[$row['main_product_id']] = $row;
    //        }
    //        
    //        $query = $this->db->query('select sub_product_id,quantity  from product_link 
    //            where operation = "-" order by main_product_id ');
    //        while ($row = $this->db->assoc($query)) {
    //            $current_cost = CommonBusiness::viewLastProductCost($row['sub_product_id']);
    //            $total_cost += $current_cost * $row['quantity'];
    //        }
    //        foreach(array_keys($prod_arr) as $prod_id=>$row){
    //            $total_cost = 0;
    //            $data[]= array('name'=>$prod_arr[$prod_id]['Product_Name'],'quantity'=>'--','cost'=>'--');
    //        }
    //    }

    public static function get_uom_conv($product_id, $uom_id) {
        $db = DBConnectorFactory::loadDriver();
        $query = $db->query('select conversion_amount from tbl_uom_conversions 
            where Product_ID = "' . $product_id . '" and uom_from="' . $uom_id . '"');
        $conv = $db->assoc($query)['conversion_amount'];
        return $conv;
    }

    public static function get_main_product_cost($id, &$cost = 0, $level = 0) {
        $db = DBConnectorFactory::loadDriver();
        //        $cost = 0;
        $query = $db->query('select * from tbl_products_link 
            where main_product_id = "' . $id . '" and operation = "-" ');
        $count = $db->rowsno($query);
        if (empty($count))
            $cost += CommonBusiness::viewLastProductCost($id);
        else {
            while ($row = $db->assoc($query)) {
                if ($level == 0) {
                    $cost = (self::get_main_product_cost($row['sub_product_id'], $cost, ++$level) * $row['quantity']);
                    //                     echo $cost.'===';
                } else {
                    $cost += CommonBusiness::viewLastProductCost($row['sub_product_id']) * $row['quantity'];
                }
                //                echo $cost.'=======';
                //            echo $row['sub_product_id'].'==='.$cost.'==';
            }
        }
        //        die();
        return $cost;
    }

    public static function get_default_uom($product_id, $type = null) {
        $db = DBConnectorFactory::loadDriver();
        //$type can be pur,inv or empty
        $cond = ' u.UOM_ID = p.UOM_ID ';
        if ($type == 'inv')
            $cond = ' u.UOM_ID = if(p.default_sales_uom=0,p.UOM_ID,p.default_sales_uom) ';
        else if ($type == 'pur')
            $cond = ' u.UOM_ID = if(p.default_purchase_uom=0,p.UOM_ID,p.default_purchase_uom) ';
        $query = $db->query('select u.* from tbl_stock_products p 
            join tbl_stock_uom u on ' . $cond . ' where Product_ID = "' . $product_id . '"');
        $row = $db->assoc($query);
        return $row;
    }

    public function get_products_to_build($options) {
        //shoud send is_sales (0,1)
        $data = array();
        $cond = ' ';
        $uom_cond = ' ';
        if (!empty($options['family']))
            $cond .= ' and family_id = "' . $options['family'] . '" ';
        if (!empty($options['category']))
            $cond .= ' and Category_ID = "' . $options['category'] . '" ';
        if($this->perm->hasPermission('Branches')){
            $cond .=   '';
        }else{
            $cond .= ' and (p.multi_branch_id in (' . (smc_session()['user_accounts']['branch_id']) . ') OR p.multi_branch_id LIKE "' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id LIKE "%,' . (smc_session()['user_accounts']['branch_id']) . ',%" OR p.multi_branch_id like "%,' . (smc_session()['user_accounts']['branch_id']) . '")';
        }

        if ($options['is_sales'] == 1)
            $uom_cond = ' u.UOM_ID = if(p.default_sales_uom=0,p.UOM_ID,p.default_sales_uom) ';
        else
            $uom_cond = ' u.UOM_ID = if(p.default_purchase_uom=0,p.UOM_ID,p.default_purchase_uom) ';
        $query = $this->db->query('
            select p.Product_ID,p.Product_Code,p.Product_Name,
            ' . ($options['is_sales'] == 1 ? 'if(p.default_sales_uom=0,p.UOM_ID,p.default_sales_uom)' : 'if(p.default_purchase_uom=0,p.UOM_ID,p.default_purchase_uom)') . ' as UOM_ID,
                u.UOM_Name
            from tbl_stock_products p 
            join tbl_stock_uom u on ' . $uom_cond . ' where 1=1 ' . $cond . '  limit 100');
        while ($row = $this->db->assoc($query)) {
            $row['qty_input'] = '<input class="qty_input " type="number" step="any" min="0" data-id="' . $row['Product_ID'] . '" data-def-uom="' . $row['UOM_ID'] . '" />';
            $row['price_input'] = '<input class="price_input " type="number" data-id="' . $row['Product_ID'] . '" step="any" min="0" />';
            unset($row['Product_ID']);
            unset($row['UOM_ID']);
            //            unset($row['Product_UOM']);
            $data[] = array_values($row);
        }
        $query_count = $this->db->query('
            select count(*) as my_count
            from tbl_stock_products p 
            join tbl_stock_uom u on ' . $uom_cond . ' where 1=1 ' . $cond);
        $row_count = $this->db->assoc($query_count)['my_count'];

        //        echo"<pre>";
        //        print_r($data);
        return ['data' => $data, 'show_alert' => ($row_count > 100 ? 1 : 0), 'row_count' => 100];
    }

    public function build_products_with_prices() {
        $product_ids = $this->info['product_ids'];
        $empty_products = !empty($this->info['empty_products']) ? $this->info['empty_products'] : array();
        $data = array();
        $condition = ' ';
        $dep_cond = ' ';
        $is_ttc = 0;
        $tax_amount = 0;
        $curr_symbol = $curr_id = '';
        $supp_curr_id = 0;
        
        if (!empty($product_ids))
            $condition .= ' and p.Product_ID in (' . implode(',', $product_ids) . ') ';
        
        if (!empty($this->info['class_id']) && !empty($empty_products)) {
            $query_class = $this->db->query('select Currency_ID, is_ttc,tax_amount from tbl_pricing_class where Class_ID = "' . $this->info['class_id'] . '"');
            $class_row = $this->db->assoc($query_class);
            $is_ttc = $class_row['is_ttc'];
            $curr_id = $class_row['Currency_ID'];
            $tax_amount = $class_row['tax_amount'];
            $curr_symbol = CurrencyFactory::getCurrencySymbol($curr_id);
        }


        if (!is_null($this->info['depot_id'])) {
            $dep_cond = 'left  join tbl_stock_product_location l on l.Location_Product_ID = p.Product_ID 
                and l.Product_Depot_ID = "' . $this->info['depot_id'] . '"';
        }
        

        $pids = array();
        $query = $this->db->query('SELECT
                                        p.Product_ID AS ID,
                                        p.is_rate,
                                        Bar_Code,
                                        p.Product_Code AS Code,
                                        p.Product_Name AS Name ,def_uom.UOM_Name as default_uom_name,
                                        ' . (!is_null($this->info['depot_id']) ? 'if(isnull(l.Product_Depot_Quantity),0,l.Product_Depot_Quantity)' : 'p.Product_Quantity') . ' AS Quantity,
                                        p.Product_VAT AS VAT,
                                        p.vat_percent,p.vat2_percent,
                                        p.is_tax,p.is_lot,p.is_serial,p.is_service,
                                        ' . ($this->info['is_sales'] == 1 ? 'if(p.default_sales_uom=0,p.UOM_ID,p.default_sales_uom)' : 'if(p.default_purchase_uom=0,p.UOM_ID,p.default_purchase_uom)' ) . ' as UOM_ID,
                                        GROUP_CONCAT(uom_from separator "/") AS Product_UOM,p.recipe_qty,
                                        p.Status_ID,
                                        p.Product_Limit_Discount,p.is_expiry,p.force_change_price,p.duration_reservation,
                                        def_view_uom.UOM_Name as def_view_uom_name

                                    FROM
                                        tbl_stock_products p
                                        inner join tbl_stock_uom def_uom on def_uom.UOM_ID = p.UOM_ID
                                        inner join tbl_stock_uom def_view_uom on def_view_uom.UOM_ID = p.default_view_uom_id
                                    inner JOIN 
                                        uom_conversions u 
                                    ON 
                                        p.Product_ID = u.Product_ID
                                    ' . $dep_cond . '

                                    WHERE

                                        1=1 ' . $condition . '
                                    GROUP BY u.Product_ID ');
        $exp_prod_ids = '';
        while ($row = $this->db->assoc($query)) {
            $row['has_optional'] = 0;
            $current_cost = CommonBusiness::viewCurrentProductCost($row["ID"]);
            $row['uom_conv'] = self::get_uom_conv($row['ID'], $row['UOM_ID']);
            if (!empty($row['uom_conv']))
                $row['Quantity'] = $row['Quantity'] / $row['uom_conv'];
            else
                $row['Quantity'] = 0;
            if ($row['is_expiry'] == 1) {
                $exp_prod_ids .= (empty($exp_prod_ids) ? '' : ',') . $row['ID'];
            }
            $row['class_currency'] = $curr_id;
            $row['Price'] = 0;
            $row['disc'] = 0;
            if (in_array($row['ID'], $empty_products)) {
                $row['Price'] = self::get_product_price($row['ID'], $this->info['class_id'], $row['UOM_ID']);
                $row['disc'] = self::get_prod_disc_by_class($row['ID'], $this->info['class_id'], $row['UOM_ID']);
            }
            if($row['is_rate'] == 1){
                $row['Price']= $this->change_product_rate($row['Price']);
            }

            $row['ttc_price'] = $row['Price'];
            $row['total_tax'] = $row['is_tax'] ? $tax_amount : 0;
            if ($is_ttc == 1) {
                if(smc_session()['default_setting']['products_without_vat']){
                    $row['ttc_price'] = ($row['Price'] * ($row['vat2_percent'] / 100))+$row['Price'];
                    $row['ttc_price'] = ($row['Price'] * ($row['vat_percent'] / 100))+$row['Price'];
                }else{
                    $row['Price'] = $row['Price'] / (1 + ($row['vat2_percent'] / 100));
                    $row['Price'] = $row['Price'] / (1 + ($row['vat_percent'] / 100));
                }
            }
            $row['LAST_COST'] = CommonBusiness::viewLastProductCost($row["ID"]);
            $row['current_cost'] = $current_cost;
            //            if (!is_null($this->info['customer_id']) && $this->perm->hasPermission('view_sales_last_price')) {
            //                $row['last_price'] = CommonBusiness::viewLastProductCustomerClassPrice($row["ID"], $this->info['customer_id'], $this->info['class_id']);
            //            } else {
            $row['last_price'] = 0;
            //            }
            //            $row['expiry_arr'] = $row['is_expiry'] == 1 ? self::get_product_expiries($row["ID"]) : '';
            $row['loc'] = '';
            $pids[] = $row['ID'];
            $data[$row['ID']] = $row;
        }
        if (!empty($exp_prod_ids) && !empty(smc_session()['default_setting']['activate_oldest_expiry_selected'])) {
            $exp_data = self::get_product_expiries($exp_prod_ids);
            foreach ($exp_data as $prod_id => $exp_row) {
                $data[$prod_id]['oldest_expiry'] = $exp_row;
            }
        }
        if (!empty($data)) {
            $query = $this->db->query('select count(*) as mycount,product_id 
                from tbl_product_options where product_id in (' . implode(',', array_keys($data)) . ') 
                group by product_id');
            while ($row = $this->db->assoc($query)) {
                $data[$row['product_id']]['has_optional'] = 1;
            }
        }
        //        echo"<pre>";
        //        die(print_r($data));
        if (!is_null($this->info['customer_id']) && $this->perm->hasPermission('view_sales_last_price')) {
            $product_ids = array_keys($data);
            $last_price_arr = CommonBusiness::viewLastProductCustomerClassPrice($product_ids, $this->info['customer_id'], $this->info['class_id']);
            foreach ($last_price_arr as $item_id => $price_item) {
                $data[$item_id]['last_price'] = $price_item;
            }
        }

        if (!empty($pids) && !is_null($this->info['depot_id']) && smc_session()['default_setting']['display_shelf_locations'] == 1) {
            $pids_arr = implode(',', $pids);
            $query_dep = $this->db->query('select GROUP_CONCAT(d.shelf_name separator ",") as loc,s.product_id
                from tbl_product_shelf s
                join tbl_shelfs_depot d on s.shelf_depot_id = d.shelf_depot_id 
                where s.product_id in (' . $pids_arr . ') and s.depot_id = "' . $this->info['depot_id'] . '" 
                    group by s.product_id');
            while ($row = $this->db->assoc($query_dep)) {
                $data[$row['product_id']]['loc'] = $row['loc'];
            }
        }
        //        if (!empty($pids) && $cmd != 1) {
        //            $pids_arr = implode(',', $pids);
        //            $query_barcode = $this->db->query('SELECT `Bar_Code`,Product_ID FROM `tbl_uom_conversions` WHERE `Product_ID` in (' . $pids_arr . ') and Is_default = 1');
        //            while ($brow = $this->db->assoc($query_barcode)) {
        //                $data[$brow['Product_ID']]['Bar_Code'] = $brow['Bar_Code'];
        //            }
        //        }

        return $data;
    }

    public static function get_prod_disc_by_class($pid, $class_id, $uom_id) {
        $db = DBConnectorFactory::loadDriver();
        $disc = 0;
        $query = $db->query('select pc.product_disc from tbl_item_price_by_classes pc
                where pc.Class_ID = "' . $class_id . '" and pc.Product_ID = "' . $pid . '" and pc.UOM_ID = "' . $uom_id . '"');
        $row = $db->assoc($query);
        if (!empty($row))
            $disc = $row['product_disc'];
        return $disc;
    }

    public function get_scale_details($id) {
        $data = array();
        $query = $this->db->query('select s.*,c.Class_Name  from `tbl_scale` `s` 
            join `tbl_pricing_class` `c` on `c`.`Class_ID` = `s`.`class_id` where s.scale_id = "' . $id . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $data = $row;
        return $data;
    }

    public function category_trial_balance() {
        $cat_arr = array();
        $cat_prod = array();
        $totals_arr = array('total' => 0, 'total_vat' => 0, 'total_vat2' => 0, 'total_amount' => 0);

        $this->get_cat_tree(0, $cat_arr);
        $cond = '';
        if (!empty($this->info['From_Date']) && !empty($this->info['To_Date'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Invoice_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
            else
                $cond .= ' and i.Purchase_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
        }
        if (!empty($this->info['date_created_from']) && !empty($this->info['date_created_to'])) {
            $from_date = $this->info['date_created_from'];
            $to_date = $this->info['date_created_to'];
            if (!empty($this->info['is_sales']) && !empty($this->info['is_end_day'])) {
                $branch_cond = '';
                if (!empty($this->info['branch_id']))
                    $branch_cond = ' and (branch_id = "' . $this->info['branch_id'] . '" or app_branch_id="' . $this->info['branch_id'] . '" ) ';
                $open_query = $this->db->query('select open_time from tbl_end_of_shift 
                    where type=1 and open_time >="' . $this->info['date_created_from'] . '" 
                        and open_time <="' . $this->info['date_created_to'] . '" ' . $branch_cond . '
                        order by shift_id asc limit 1');
                $row_open = $this->db->assoc($open_query);
                if (!empty($row_open))
                    $from_date = $row_open['open_time'];
                else
                    $from_date = date('Y-m-d', strtotime($this->info['date_created_from'])) . ' ' . smc_session()['default_setting']['default_start_time'];
                //
                $close_query = $this->db->query('select close_time from tbl_end_of_shift 
                    where type=1 and close_time <="' . $this->info['date_created_to'] . '" 
                        and close_time >="' . $this->info['date_created_from'] . '" ' . $branch_cond . '
                        order by shift_id desc limit 1');
                $row_close = $this->db->assoc($close_query);
                if (!empty($row_close))
                    $to_date = $row_close['close_time'];
                else
                    $to_date = date('Y-m-d', strtotime($this->info['date_created_to'])) . ' ' . date('H:i:s', strtotime(smc_session()['default_setting']['default_start_time'] . ' -1 second'));
            }
            $cond .= ' and i.date_created between "' . $from_date . '" and "' . $to_date . '" ';
        }
        if (!empty($this->info['customer_id'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Customer_ID = "' . $this->info['customer_id'] . '" ';
            else
                $cond .= '  and i.Supplier_ID = "' . $this->info['customer_id'] . '" ';
        }
        if (!empty($this->info['users']))
            $cond .= ' and i.Logged_ID in (' . $this->info['users'] . ') ';
        if (empty($this->info['is_actual']))
            $cond .= ' and i.is_actual = "' . $this->info['is_actual'] . '" ';
        if (!empty($this->info['branch_id']))
            $cond .= ' and i.branch_id = "' . $this->info['branch_id'] . '" ';
        if (!empty($this->info['sales_man_id']) && !empty($this->info['is_sales']))
            $cond .= ' and i.Sales_ID = "' . $this->info['sales_man_id'] . '" ';
        if ($this->info['is_sales'] == 1) {
            if (!empty($this->info['group_id'])) {
                $cust_ids = array();
                $query = $this->db->prepare_Stmt('select Customer_ID from tbl_customers 
                where customer_group_id = ?', [$this->info['group_id']]);
                while ($row = $this->db->assoc($query))
                    $cust_ids[] = $row['Customer_ID'];
                if (!empty($cust_ids))
                    $cond .= ' AND i.Customer_ID in (' . implode(',', $cust_ids) . ') ';
                else
                    $cond .= ' and 1=2 ';
            }
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
                sum(d.`Product_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
                u.UOM_Name,
            sum(Product_Total_Price * current_rate) as total,
            sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
            p.Category_ID,0 as is_parent 
            from tbl_invoice_products_details d join tbl_invoices i using(Invoice_ID_Auto) 
            join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)
            where 1=1 ' . $cond . ' group by Product_ID');
        } else {
            if (!empty($this->info['group_id'])) {
                $supp_ids = array();
                $query = $this->db->prepare_Stmt('select Supplier_ID from  tbl_stock_suppliers 
                where supplier_group_id = ?', [$this->info['group_id']]);
                while ($row = $this->db->assoc($query))
                    $cust_ids[] = $row['Supplier_ID'];
                if (!empty($supp_ids))
                    $cond .= ' AND i.Supplier_ID in (' . implode(',', $supp_ids) . ') ';
                else
                    $cond .= ' and 1=2 ';
            }
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
               sum(d.`Item_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
            u.UOM_Name,
            sum(Product_Total_Price * current_rate) as total,
            sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
            p.Category_ID,0 as is_parent 
            from tbl_inventory_purchase_items d join tbl_inventory_purchases i using(Purchase_ID_Auto) 
             join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)
            where 1=1 ' . $cond . ' group by Product_ID');
        }
        while ($row = $this->db->assoc($query)) {
            $cat_prod[$row['Category_ID']][$row['id']] = $row;
            $cat_arr[$row['Category_ID']]['total'] += $row['total'];
            $cat_arr[$row['Category_ID']]['vat1_total'] += $row['vat1_total'];
            if (smc_session()['default_setting']['activate_second_vat'] == 1) {
                $cat_arr[$row['Category_ID']]['vat2_total'] += $row['vat2_total'];
            }
            $cat_arr[$row['Category_ID']]['total_with_vat'] += $row['total_with_vat'];
            $totals_arr['total'] += $row['total'];
            $totals_arr['total_vat'] += $row['vat1_total'];
            $totals_arr['total_vat2'] += $row['vat2_total'];
            $totals_arr['total_amount'] += $row['total_with_vat'];
        }
        //                echo "<pre>";
        //        die(print_r($cat_arr));
        //        $prod_totals = self::get_product_total_sales($cat_arr);
        $data = array();
        $space = "&nbsp;&nbsp;&nbsp;";
        foreach ($cat_arr as $cat_id => $cat_row) {
            $shift = $cat_row['shift'];
            unset($cat_row['is_parent']);
            unset($cat_row['id']);
            unset($cat_row['shift']);
            if (smc_session()['default_setting']['activate_second_vat'] == 0) {
                unset($cat_row['vat2_total']);
            } else {
                $cat_row['vat2_total'] = CommonFunctions::formatNumber($cat_row['vat2_total']);
            }
            $cat_row['name'] = str_repeat($space, $shift) . $cat_row['name'];
            $cat_row['total'] = CommonFunctions::formatNumber($cat_row['total']);
            $cat_row['vat1_total'] = CommonFunctions::formatNumber($cat_row['vat1_total']);
            $cat_row['total_with_vat'] = CommonFunctions::formatNumber($cat_row['total_with_vat']);
            $cat_row = array_values($cat_row);
            $cat_row['class'] = 'bold text-left ' . ($this->info['type'] != 1 ? ' bg-gray' : '');
            if ($this->info['type'] == 0 || $this->info['type'] == 1)
                $data[] = $cat_row;
            if (!empty($cat_prod[$cat_id]) && ($this->info['type'] == 0 || $this->info['type'] == 2)) {
                foreach ($cat_prod[$cat_id] as $prod_row) {
                    $prod_row['name'] = $prod_row['name'] = str_repeat($space, $shift + 1) . $prod_row['name'];
                    $prod_row['total'] = CommonFunctions::formatNumber($prod_row['total']);
                    $prod_row['vat1_total'] = CommonFunctions::formatNumber($prod_row['vat1_total']);
                    $prod_row['total_with_vat'] = CommonFunctions::formatNumber($prod_row['total_with_vat']);
                    $prod_row['qty'] = CommonFunctions::formatNumber($prod_row['qty']) . ' ' . $prod_row['UOM_Name'];
                    unset($prod_row['Category_ID']);
                    unset($prod_row['UOM_Name']);
                    unset($prod_row['is_parent']);
                    unset($prod_row['id']);
                    if (smc_session()['default_setting']['activate_second_vat'] == 0) {
                        unset($prod_row['vat2_total']);
                    } else {
                        $prod_row['vat2_total'] = CommonFunctions::formatNumber($prod_row['vat2_total']);
                    }
                    $prod_row = array_values($prod_row);
                    $prod_row['class'] = 'text-left';
                    $data[] = $prod_row;
                }
            }
        }
        return ['data' => $data, 'totals' => $totals_arr];
        //        echo "<pre>";
        //        die(print_r($data));
    }

    public function get_cat_tree($parent_id, &$cat_arr, $shift = 0) {
        $query = $this->db->query('select Cat_ID as id,Cat_Name as name,"" as qty,0 as total,
            0 as vat1_total,0 as vat2_total,0 as total_with_vat,
            1 as is_parent from tbl_product_cat 
            where Parent_ID = "' . $parent_id . '"  order by Cat_ID');
        while ($row = $this->db->assoc($query)) {
            $row['shift'] = $shift;
            $cat_arr[$row['id']] = $row;
            self::get_cat_tree($row['id'], $cat_arr, $shift + 1);
        }
    }

    public function delete_product_expense($id_arr) {
        $this->db->query('START TRANSACTION');
        foreach ($id_arr as $id) {
            $this->db->prepare_Stmt("DELETE FROM tbl_accounting_transactions  WHERE main_id= ?
             AND main_type= 'mex' ", [&$id]);
            //
            $query = $this->db->query("SELECT 
                                        if(isNull(l.link_id), parts.part_product_id, l.sub_product_id) as sub_product_id,
                                        if(isNull(l.link_id), p.current_quantity, (p.default_quantity * l.current_quantity)) as Current_Quantity,
                                        if(isNull(l.link_id), p.current_quantity, (p.default_quantity * l.quantity)) as Quantity,
                                        if(isNull(l.link_id), p.UOM_ID, l.UOM_ID) as UOM_ID,
                                        if(isNull(l.link_id), '-', l.operation) as operation,
                                        i.Depot_ID,
                                        i.date_time,
                                        if(isNull(l.link_id), 0, 1) as link_id,
                                        i.prefix,i.is_actual, 
                                        i.expense_nb,i.created_logged_id,i.date_created,p.cost,i.expense_date_time,pr.is_service
                                    FROM 
                                        tbl_product_expense_details p
                                    left JOIN
                                     tbl_stock_products_parts parts on parts.part_id = p.part_product_id
                                        left join tbl_products_link l
                                    on parts.part_product_id = l.main_product_id
                                    join tbl_product_expenses i on i.expense_id = p.expense_id
                                    join tbl_stock_products pr on pr.Product_ID = if(isNull(l.link_id), parts.part_product_id, l.sub_product_id)
                                    WHERE 
                                        p.expense_id = '" . $id . "'
                ");
            //
            while ($row = $this->db->assoc($query)) {
                $date = explode(' ', $row['expense_date_time'])[0];
                $sub_cost = $row['link_id'] == 0 ? $row['cost'] : CommonBusiness::viewCurrentProductCost($row['sub_product_id']);
                $costdata = [
                    "Product_ID" => $row['sub_product_id'],
                    "Quantity" => $row['Quantity'],
                    "Unit_Cost" => $sub_cost,
                    "Currency_ID" => smc_session()['local_currency'],
                    "date_time" => $row['date_time'],
                    "current_rate" => 1,
                    "depot_id" => $row['Depot_ID'],
                    "trans_date" => $date,
                    "current_quantity" => $row['Current_Quantity'],
                    "uom_id" => $row['UOM_ID'],
                    "is_actual" => $row['is_actual'],
                    "expiry_date" => null,
                    "main_id" => $id,
                    "is_service" => $row['is_service'],
                    "main_nb" => ($row['prefix'] . $row['expense_nb'])
                ];

                CommonBusiness::updateLinkQuantities($costdata, "delete_machine_maintenance", ($row['operation'] == '+' ? '-' : '+'));
            }
            CommonBusiness::update_trans_record_current('mch', $id);


            $this->db->prepare_Stmt('delete from tbl_product_expense_details where expense_id = ?', [&$id]);
            $this->db->prepare_Stmt('delete from tbl_product_expense_accounts where expense_id = ?', [&$id]);
            $this->db->prepare_Stmt('delete from  `tbl_product_expenses` where expense_id = ?', [&$id]);
        }
        $error = $this->db->error();
        if (empty($error))
            $this->db->query('COMMIT');
        else
            $this->db->query('ROLLBACK');
        return $error;
    }

    public function search_additional_barcodes($product_id, $term) {
        $barcodes = '';
        $data = array();
        $cols = [
            "%" . $term . "%"
        ];
        $query = $this->db->prepare_Stmt('select Bar_Code,additional_barcodes from tbl_uom_conversions 
            where Product_ID="' . $product_id . '" 
                and concat(",",Bar_Code,",",additional_barcodes,",") LIKE ? ', $cols);
        while ($row = $this->db->assoc($query)) {
            $barcodes = empty($barcodes) ? $row['Bar_Code'] : $barcodes . ',' . $row['Bar_Code'];
            $barcodes = empty($barcodes) ? $row['additional_barcodes'] : $barcodes . ',' . $row['additional_barcodes'];
        }
        //        echo $barcodes . '===';
        $barcode_arr = !empty($barcodes) ? explode(",", $barcodes) : array();
        foreach ($barcode_arr as $barcode) {
            if (!empty($term)) {
                if (strpos(strtolower($barcode), strtolower($term)) !== false) {
                    array_push($data, ["text" => $barcode]);
                }
            } else {
                array_push($data, ["text" => $barcode]);
            }
        }
        return $data;
    }

    public function add_cust_supp_codes() {
        $this->db->query('START TRANSACTION');
        foreach ($this->info['prod_arr'] as $row) {
            $cust_id = $this->info['is_cust'] == 1 ? $this->info['person_id'] : null;
            $supp_id = $this->info['is_cust'] == 0 ? $this->info['person_id'] : null;
            $data = [$cust_id, $supp_id, $row['product_id'], $row['product_code'], $row['product_code']];
            $this->db->prepare_Stmt('INSERT INTO `tbl_cust_supp_prod_codes`( `customer_id`,supplier_id, `product_id`,
                `product_code`) value(?,?,?,?) ON DUPLICATE KEY UPDATE product_code = ?', $data);
        }
        $error = $this->db->error();
        if (empty($error)) {
            $this->db->query('COMMIT');
        } else {
            $this->db->query('ROLLBACK');
        }
        return $error;
    }

    public function submit_add_disc_report() {
        $this->db->query('START TRANSACTION');
        foreach ($this->info['add_disc_arr'] as $add_disc_row) {
            $data = [$add_disc_row['category_id'], $add_disc_row['percent'],
                $add_disc_row['current_type'], $add_disc_row['start_date']];
            $this->db->prepare_Stmt('INSERT INTO `tbl_add_discount_report_setting`
            ( `category_id`,`percent`,`current_type`, `start_date`) VALUES (?,?,?,?)', $data);
        }
        $error = $this->db->error();
        if (empty($error))
            $this->db->query('COMMIT');
        else
            $this->db->query('ROLLBACK');
        return $error;
    }

    public function edit_add_disc_report() {
        $add_disc_row = $this->info['add_disc_arr'][0];
        $data = [$add_disc_row['category_id'], $add_disc_row['percent'],
            $add_disc_row['current_type'], $add_disc_row['start_date'], $add_disc_row['report_setting_id']];
        $this->db->prepare_Stmt('update `tbl_add_discount_report_setting` set `category_id`=?,
                `percent`=?,`current_type` = ?, `start_date`=? where report_setting_id = ?', $data);
        $error = $this->db->error();
        return $error;
    }

    public function get_add_disc_report_by_id($id) {
        $data = array();
        $query = $this->db->query('select s.*,c.Cat_Name
            from tbl_add_discount_report_setting s join tbl_product_cat c on s.category_id = c.Cat_ID
            where report_setting_id="' . $id . '"');
        $data = $this->db->assoc($query);
        return $data;
    }

    public function delete_add_discount_report($id) {
        $this->db->prepare_Stmt('delete from tbl_add_discount_report_setting where report_setting_id="' . $id . '" ');
        $error = $this->db->error();
        return $error;
    }

    public function return_cat_disc($add_disc_arr, $cur_date) {
        $percent = 0;
        foreach ($add_disc_arr as $date => $row) {
            if ($cur_date < $date)
                break;
            $percent = $row['percent'];
        }
        return $percent;
    }

    public function cat_trial_blanc_with_disc_report() {
        $cat_arr = array();
        $cat_prod = array();
        $cat_arr_disc = array();
        $cat_prod_disc = array();
        $add_disc_arr = array();
        $totals_arr = array('total' => 0, 'total_vat' => 0, 'total_vat2' => 0, 'total_amount' => 0);
        //
        $query = $this->db->query('select * from  tbl_add_discount_report_setting 
            order by category_id,start_date');
        while ($row = $this->db->assoc($query)) {
            $add_disc_arr[$row['category_id']] = ['percent' => $row['percent'],
                'type' => $row['current_type']];
            //            $add_disc_arr[$row['category_id']][$row['start_date']] = $row;
        }
        //
        $this->get_cat_tree(0, $cat_arr);
        $cat_arr_disc = $cat_arr;
        $cond = '';
        if (!empty($this->info['From_Date']) && !empty($this->info['To_Date'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Invoice_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
            else
                $cond .= ' and i.Purchase_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
        }
        if (!empty($this->info['date_created_from']) && !empty($this->info['date_created_to'])) {
            $from_date = $this->info['date_created_from'];
            $to_date = $this->info['date_created_to'];
            if (!empty($this->info['is_sales']) && !empty($this->info['is_end_day'])) {
                $branch_cond = '';
                if (!empty($this->info['branch_id']))
                    $branch_cond = ' and (branch_id = "' . $this->info['branch_id'] . '" or app_branch_id="' . $this->info['branch_id'] . '" ) ';

                $open_query = $this->db->query('select open_time from tbl_end_of_shift 
                    where type=1 and open_time >="' . $this->info['date_created_from'] . '" 
                        and open_time <="' . $this->info['date_created_to'] . '" ' . $branch_cond . '
                        order by shift_id asc limit 1');
                $row_open = $this->db->assoc($open_query);
                if (!empty($row_open))
                    $from_date = $row_open['open_time'];
                else
                    $from_date = date('Y-m-d', strtotime($this->info['date_created_from'])) . ' ' . smc_session()['default_setting']['default_start_time'];
                //
                $close_query = $this->db->query('select close_time from tbl_end_of_shift 
                    where type=1 and close_time <="' . $this->info['date_created_to'] . '" 
                        and close_time >="' . $this->info['date_created_from'] . '" ' . $branch_cond . '
                        order by shift_id desc limit 1');
                $row_close = $this->db->assoc($close_query);
                if (!empty($row_close))
                    $to_date = $row_close['close_time'];
                else
                    $to_date = date('Y-m-d', strtotime($this->info['date_created_to'])) . ' ' . date('H:i:s', strtotime(smc_session()['default_setting']['default_start_time'] . ' -1 second'));
            }
            //            echo $from_date.'==='.$to_date;
            $cond .= ' and i.date_created between "' . $from_date . '" and "' . $to_date . '" ';
        }
        if (!empty($this->info['customer_id'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Customer_ID = "' . $this->info['customer_id'] . '" ';
            else
                $cond .= '  and i.Supplier_ID = "' . $this->info['customer_id'] . '" ';
        }
        if (!empty($this->info['users']))
            $cond .= ' and i.Logged_ID in (' . $this->info['users'] . ') ';
        if (empty($this->info['is_actual']))
            $cond .= ' and i.is_actual = "' . $this->info['is_actual'] . '" ';
        if (!empty($this->info['branch_id']))
            $cond .= ' and i.branch_id = "' . $this->info['branch_id'] . '" ';
        if (!empty($this->info['sales_man_id']) && !empty($this->info['is_sales']))
            $cond .= ' and i.Sales_ID = "' . $this->info['sales_man_id'] . '" ';
        if ($this->info['is_sales'] == 1) {
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
                sum(d.`Product_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
                u.UOM_Name,i.Invoice_Date as cur_date,
            sum(Product_Total_Price * current_rate) as total,
            sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
            p.Category_ID,0 as is_parent 
            from tbl_invoice_products_details d join tbl_invoices i using(Invoice_ID_Auto) 
            join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)
            where 1=1  ' . $cond . ' group by d.Product_ID');
        } else {
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
                sum(d.`Item_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
                u.UOM_Name,i.Purchase_Date as cur_date,
                sum(Product_Total_Price * current_rate) as total,
                sum(vat_amount * current_rate) as vat1_total,
                sum(vat2_amount * current_rate) as vat2_total,
                sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
                p.Category_ID,0 as is_parent 
            from tbl_inventory_purchase_items d join tbl_inventory_purchases i using(Purchase_ID_Auto) 
            join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)            
            where 1=1 ' . $cond . ' group by d.Product_ID');
        }
        while ($row = $this->db->assoc($query)) {
            $disc = 0;
            $sign = 'minus';
            if (!empty($add_disc_arr[$row['Category_ID']])) {
                $disc = $add_disc_arr[$row['Category_ID']]['percent'];
                $sign = $add_disc_arr[$row['Category_ID']]['type'] == 1 ? 'minus' : 'plus';
            }
            if ($sign == 'minus') {
                $disc_ratio = (100 - $disc) / 100;
            } else {
                $disc_ratio = (100 + $disc) / 100;
            }
            //fill array after cat discount
            $qty = round($row['qty'] * $disc_ratio);

            if ($qty < 1)
                $qty = 1;
            if ($row['qty'] > 0) {
                $row['total'] = $row['total'] * $qty / $row['qty'];
                $row['vat1_total'] = $row['vat1_total'] * $qty / $row['qty'];
                $row['vat2_total'] = $row['vat2_total'] * $qty / $row['qty'];
                $row['total_with_vat'] = $row['total_with_vat'] * $qty / $row['qty'];
                $row['qty'] = $qty;
            } else {
                $row['total'] = $row['vat1_total'] = $row['vat2_total'] = $row['total_with_vat'] = $row['qty'] = 0;
            }
            if (!empty($cat_prod[$row['Category_ID']][$row['id']])) {
                $cat_prod[$row['Category_ID']][$row['id']]['total'] += $row['total'];
                $cat_prod[$row['Category_ID']][$row['id']]['vat1_total'] += $row['vat1_total'];
                $cat_prod[$row['Category_ID']][$row['id']]['vat2_total'] += $row['vat2_total'];
                $cat_prod[$row['Category_ID']][$row['id']]['total_with_vat'] += $row['total_with_vat'];
                $cat_prod[$row['Category_ID']][$row['id']]['qty'] += $qty;
            } else {
                $cat_prod[$row['Category_ID']][$row['id']] = $row;
            }
            $cat_arr[$row['Category_ID']]['total'] += $row['total'];
            $cat_arr[$row['Category_ID']]['vat1_total'] += $row['vat1_total'];
            if (smc_session()['default_setting']['activate_second_vat'] == 1) {
                $cat_arr[$row['Category_ID']]['vat2_total'] += $row['vat2_total'];
            }
            $cat_arr[$row['Category_ID']]['total_with_vat'] += $row['total_with_vat'];
            $totals_arr['total'] += $row['total'];
            $totals_arr['total_vat'] += $row['vat1_total'];
            $totals_arr['total_vat2'] += $row['vat2_total'];
            $totals_arr['total_amount'] += $row['total_with_vat'];
        }

        $data = array();
        $space = "&nbsp;&nbsp;&nbsp;";
        foreach ($cat_arr as $cat_id => $cat_row) {

            //            echo '<pre>';
            //            print_r($cat_row);
            $shift = $cat_row['shift'];
            unset($cat_row['is_parent']);
            unset($cat_row['id']);
            unset($cat_row['shift']);
            if (smc_session()['default_setting']['activate_second_vat'] == 0) {
                unset($cat_row['vat2_total']);
            } else {
                $cat_row['vat2_total'] = CommonFunctions::formatNumber($cat_row['vat2_total']);
            }
            $current_category_total = $cat_row['total_with_vat'];
            $cat_row['name'] = str_repeat($space, $shift) . $cat_row['name'];
            $cat_row['total'] = CommonFunctions::formatNumber($cat_row['total']);
            $cat_row['vat1_total'] = CommonFunctions::formatNumber($cat_row['vat1_total']);
            $cat_row['total_with_vat'] = CommonFunctions::formatNumber($cat_row['total_with_vat']);
            $cat_row = array_values($cat_row);
            $cat_row['class'] = 'bold text-left ' . ($this->info['type'] != 1 ? ' bg-gray' : '');
            if (($this->info['type'] == 0 || $this->info['type'] == 1) && !empty($current_category_total))
                $data[] = $cat_row;
            if (!empty($cat_prod[$cat_id]) && ($this->info['type'] == 0 || $this->info['type'] == 2)) {
                foreach ($cat_prod[$cat_id] as $prod_row) {
                    $current_total_with_vat = $prod_row['total_with_vat'];
                    $prod_row['name'] = $prod_row['name'] = str_repeat($space, $shift + 1) . $prod_row['name'];
                    $prod_row['total'] = CommonFunctions::formatNumber($prod_row['total']);
                    $prod_row['vat1_total'] = CommonFunctions::formatNumber($prod_row['vat1_total']);
                    $prod_row['total_with_vat'] = CommonFunctions::formatNumber($prod_row['total_with_vat']);
                    $prod_row['qty'] = CommonFunctions::formatNumber($prod_row['qty']) . ' ' . $prod_row['UOM_Name'];
                    unset($prod_row['Category_ID']);
                    unset($prod_row['UOM_Name']);
                    unset($prod_row['is_parent']);
                    unset($prod_row['id']);
                    unset($prod_row['cur_date']);
                    if (smc_session()['default_setting']['activate_second_vat'] == 0) {
                        unset($prod_row['vat2_total']);
                    } else {
                        $prod_row['vat2_total'] = CommonFunctions::formatNumber($prod_row['vat2_total']);
                    }
                    $prod_row = array_values($prod_row);
                    $prod_row['class'] = 'text-left';
                    if (!empty($current_total_with_vat))
                        $data[] = $prod_row;
                }
            }
        }
        return ['data' => $data, 'totals' => $totals_arr];
    }

    public function cat_trial_blanc_with_disc_report_p_day() {
        $cat_arr = array();
        $cat_prod = array();
        $cat_arr_disc = array();
        //        $cat_prod_disc = array();
        $add_disc_arr = array();
        //        $totals_arr = array('total' => 0, 'total_vat' => 0, 'total_vat2' => 0, 'total_amount' => 0);
        //
        $query = $this->db->query('select * from  tbl_add_discount_report_setting 
            order by category_id,start_date');
        while ($row = $this->db->assoc($query)) {
            $add_disc_arr[$row['category_id']] = ['percent' => $row['percent'],
                'type' => $row['current_type']];
            //            $add_disc_arr[$row['category_id']][$row['start_date']] = $row;
        }
        //
        $this->get_cat_tree(0, $cat_arr);
        $cat_arr_disc = $cat_arr;
        $cond = '';
        if (!empty($this->info['From_Date']) && !empty($this->info['To_Date'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Invoice_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
            else
                $cond .= ' and i.Purchase_Date between "' . $this->info['From_Date'] . '" and "' . $this->info['To_Date'] . '" ';
        }
        if (!empty($this->info['date_created_from']) && !empty($this->info['date_created_to'])) {
            $from_date = $this->info['date_created_from'];
            $to_date = $this->info['date_created_to'];
            if (!empty($this->info['is_sales']) && !empty($this->info['is_end_day'])) {
                $branch_cond = '';
                if (!empty($this->info['branch_id']))
                    $branch_cond = ' and (branch_id = "' . $this->info['branch_id'] . '" or app_branch_id="' . $this->info['branch_id'] . '" ) ';

                $open_query = $this->db->query('select open_time from tbl_end_of_shift 
                    where type=1 and open_time >="' . $this->info['date_created_from'] . '" 
                        and open_time <="' . $this->info['date_created_to'] . '" ' . $branch_cond . '
                        order by shift_id asc limit 1');
                $row_open = $this->db->assoc($open_query);
                if (!empty($row_open))
                    $from_date = $row_open['open_time'];
                else
                    $from_date = date('Y-m-d', strtotime($this->info['date_created_from'])) . ' ' . smc_session()['default_setting']['default_start_time'];
                //
                $close_query = $this->db->query('select close_time from tbl_end_of_shift 
                    where type=1 and close_time <="' . $this->info['date_created_to'] . '" 
                        and close_time >="' . $this->info['date_created_from'] . '" ' . $branch_cond . '
                        order by shift_id desc limit 1');
                $row_close = $this->db->assoc($close_query);
                if (!empty($row_close))
                    $to_date = $row_close['close_time'];
                else
                    $to_date = date('Y-m-d', strtotime($this->info['date_created_to'])) . ' ' . date('H:i:s', strtotime(smc_session()['default_setting']['default_start_time'] . ' -1 second'));
            }
            //            echo $from_date.'==='.$to_date;
            $cond .= ' and i.date_created between "' . $from_date . '" and "' . $to_date . '" ';
        }
        if (!empty($this->info['customer_id'])) {
            if (!empty($this->info['is_sales']))
                $cond .= ' and i.Customer_ID = "' . $this->info['customer_id'] . '" ';
            else
                $cond .= '  and i.Supplier_ID = "' . $this->info['customer_id'] . '" ';
        }
        if (!empty($this->info['users']))
            $cond .= ' and i.Logged_ID in (' . $this->info['users'] . ') ';
        if (empty($this->info['is_actual']))
            $cond .= ' and i.is_actual = "' . $this->info['is_actual'] . '" ';
        if (!empty($this->info['branch_id']))
            $cond .= ' and i.branch_id = "' . $this->info['branch_id'] . '" ';
        if (!empty($this->info['sales_man_id']) && !empty($this->info['is_sales']))
            $cond .= ' and i.Sales_ID = "' . $this->info['sales_man_id'] . '" ';
        if ($this->info['is_sales'] == 1) {
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
                sum(d.`Product_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
                u.UOM_Name,i.Invoice_Date as cur_date,
            sum(Product_Total_Price * current_rate) as total,
            sum(vat_amount * current_rate) as vat1_total,
             sum(vat2_amount * current_rate) as vat2_total,
             sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
            p.Category_ID,0 as is_parent 
            from tbl_invoice_products_details d join tbl_invoices i using(Invoice_ID_Auto) 
            join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)
            where 1=1  ' . $cond . ' group by d.Product_ID,i.Invoice_Date order by i.Invoice_Date asc');
        } else {
            $query = $this->db->query('select d.Product_ID as id,
                concat(p.Product_Code," - ",p.Product_Name) as name,
                sum(d.`Item_Quantity`/if(p.default_view_uom_id=0,1,p.default_view_rate))  as qty,
                u.UOM_Name,i.Purchase_Date as cur_date,
                sum(Product_Total_Price * current_rate) as total,
                sum(vat_amount * current_rate) as vat1_total,
                sum(vat2_amount * current_rate) as vat2_total,
                sum((Product_Total_Price+vat_amount+vat2_amount) * current_rate) as total_with_vat,
                p.Category_ID,0 as is_parent 
            from tbl_inventory_purchase_items d join tbl_inventory_purchases i using(Purchase_ID_Auto) 
            join tbl_stock_products p using(Product_ID)
            join tbl_stock_uom u on u.UOM_ID = if(p.default_view_uom_id=0,p.UOM_ID,p.default_view_uom_id)            
            where 1=1 ' . $cond . ' group by d.Product_ID,i.Purchase_Date order by i.Purchase_Date asc');
        }
        while ($row = $this->db->assoc($query)) {
            $disc = 0;
            $sign = 'minus';
            if (!empty($add_disc_arr[$row['Category_ID']])) {
                $disc = $add_disc_arr[$row['Category_ID']]['percent'];
                $sign = $add_disc_arr[$row['Category_ID']]['type'] == 1 ? 'minus' : 'plus';
            }
            if ($sign == 'minus') {
                $disc_ratio = (100 - $disc) / 100;
            } else {
                $disc_ratio = (100 + $disc) / 100;
            }
            //fill array after cat discount
            $qty = round($row['qty'] * $disc_ratio);

            if ($qty < 1)
                $qty = 1;
            if ($row['qty'] > 0) {
                $row['total'] = $row['total'] * $qty / $row['qty'];
                $row['vat1_total'] = $row['vat1_total'] * $qty / $row['qty'];
                $row['vat2_total'] = $row['vat2_total'] * $qty / $row['qty'];
                $row['total_with_vat'] = $row['total_with_vat'] * $qty / $row['qty'];
                $row['qty'] = $qty;
            } else {
                $row['total'] = $row['vat1_total'] = $row['vat2_total'] = $row['total_with_vat'] = $row['qty'] = 0;
            }
            if (empty($cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['total'])) {
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['total'] = 0;
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['vat1_total'] = 0;
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['vat2_total'] = 0;
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['total_with_vat'] = 0;
            }
            if (!empty($cat_prod[$row['cur_date']][$row['Category_ID']]['items'][$row['id']])) {
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']]['total'] += $row['total'];
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']]['vat1_total'] += $row['vat1_total'];
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']]['vat2_total'] += $row['vat2_total'];
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']]['total_with_vat'] += $row['total_with_vat'];
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']]['qty'] += $qty;
            } else {
                $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['items'][$row['id']] = $row;
            }
            $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['total'] += $row['total'];
            $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['vat1_total'] += $row['vat1_total'];
            $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['vat2_total'] += $row['vat2_total'];
            $cat_prod[$row['cur_date']]['cat'][$row['Category_ID']]['total_with_vat'] += $row['total_with_vat'];
        }
        return ['cat_arr' => $cat_arr, 'cat_prod' => $cat_prod];
    }

    public function submit_pur_cat() {
        if ($this->info['pur_cat_id'] == 0) {
            $this->db->prepare_Stmt('INSERT INTO `tbl_purchase_cat`( `pur_cat_name`) 
                VALUES (?) ', [&$this->info['pur_cat_name']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_purchase_cat SET pur_cat_name =?
              WHERE pur_cat_id =? ', [&$this->info['pur_cat_name'], &$this->info['pur_cat_id']]);
        }
        $error = $this->db->error();
        return array_unique($error);
    }

    public function delete_pur_cat() {

        $query = $this->db->prepare_stmt('select * from tbl_stock_products where pur_cat_id = ?', [&$this->info['entry_value']]);
        $row_count = $this->db->rowsno($query);
        if ($row_count == 0) {
            $this->db->prepare_Stmt('Delete from tbl_purchase_cat where pur_cat_id = ?
                                         ', [&$this->info['entry_value']]);
            $error = $this->db->error();
        } else {
            $error = CommonLanguage::getMessage('pur_cat_used');
        }

        return $error;
    }

    public function submit_display() {
        $display_id = $this->info['display_id'];
        $this->info['printer_ids'] = !empty($this->info['printer_ids']) ? $this->info['printer_ids'] : NULL;
        if ($display_id == 0) {
            $this->db->prepare_Stmt('INSERT INTO tbl_display
                                     (display_name,display_blocks,printer_ids,hide_done_order,hide_done_details)
                                     VALUES
                                    (?,?,?,?,?) ', [&$this->info['display_name'], &$this->info['display_blocks'],
                &$this->info['printer_ids'], &$this->info['hide_done_order'],
                &$this->info['hide_done_details']]);
        } else {
            $this->db->prepare_Stmt('UPDATE tbl_display
                                     SET
                                            display_name = ?,
                                            display_blocks = ?,
                                            printer_ids = ?,
                                            hide_done_order = ?,
                                            hide_done_details = ?
                                     WHERE 
                                            display_id =?
                                         ', [&$this->info['display_name'], &$this->info['display_blocks'],
                &$this->info['printer_ids'], &$this->info['hide_done_order'],
                &$this->info['hide_done_details'], &$display_id]);
        }
        $error = $this->db->error();
        return $error;
    }

    public function delete_display($display_id) {
        $this->db->prepare_Stmt('delete from tbl_display where display_id = ?', [&$display_id]);
        $error = $this->db->error();
        return $error;
    }

    public function get_display($display_id) {
        $data = array('main' => array(), 'details' => array());
        $query_main = $this->db->prepare_Stmt('select * from tbl_display  where display_id = ?', [&$display_id]);
        $data['main'] = $this->db->assoc($query_main);
        if (!empty($data['main']['printer_ids'])) {
            $printer_query = $this->db->query('select printer_id as id,printer_name as text  
                                            from tbl_printers 
                                            where printer_id in (' . $data['main']['printer_ids'] . ')');

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

    public function get_prod_options($id) {
        $data = array();
        $query = $this->db->query('select * from tbl_product_options where product_id = "' . $id . '"');
        while ($row = $this->db->assoc($query)) {
            $data[$row['option_id']] = $row;
        }
        if (!empty($data)) {
            $query = $this->db->query('select d.*,
                concat_ws("",p.Product_Code," - ",p.Product_Name," (",u.UOM_Name,") ") as product_name,
            u.UOM_Name
            from tbl_product_option_details d 
            join tbl_stock_products p on p.Product_ID = d.sub_product_id
            join tbl_stock_uom u on u.UOM_ID = d.UOM_ID where option_id in (' . implode(',', array_keys($data)) . ') ');
            while ($row = $this->db->assoc($query)) {
                $data[$row['option_id']]['details'][] = $row;
            }
        }

        return array_values($data);
    }

    public function get_cat_child($cat_id, &$child_arr) {
        $child_arr[$cat_id] = $cat_id;
        $query = $this->db->query('select Cat_ID as id from tbl_product_cat 
            where Parent_ID = "' . $cat_id . '" ');
        while ($row = $this->db->assoc($query)) {
            $child_arr[$row['id']] = $row['id'];
            self::get_cat_tree($row['id'], $child_arr);
        }
    }

    public static function count_expire_product() {
        $db = DBConnectorFactory::loadDriver();

            $query =$db->query('SELECT
            trans.Transaction_ID,
            trans.Product_ID,
            (
                trans.Product_Quantity / products.default_view_rate
            ) AS Product_Quantity,
            trans.lot_nb,
            trans.serial_nb,
            SUM(
                IF(
                    trans.Operation_Type = "-",
                    trans.Product_Quantity *(-1),
                    trans.Product_Quantity
                ) / products.default_view_rate
            ) AS sum_quantity,
            trans.expiry_date,
            products.Product_Code,
            products.Product_Name,
            products.Category_ID,
            uom.UOM_Name,
            Operation_Type
        FROM
            tbl_stock_product_transactions trans
        INNER JOIN tbl_stock_products products USING(Product_id)
        INNER JOIN tbl_stock_uom uom ON
            products.default_view_uom_id = uom.UOM_ID
        WHERE
            trans.expiry_date <> ""  and CURDATE() >= DATE_SUB(trans.expiry_date, INTERVAL '.smc_session()['default_setting']['product_expiry_alert_days'] .' DAY)
        GROUP BY 
            trans.Product_ID,
            trans.expiry_date
        HAVING
            sum_quantity <> 0');
            $count = $db->rowsno($query);
            return $count;
    }
    public function change_product_rate($price) {
        if(smc_session()['default_setting']['product_rate'] > 0){
            $price= ($price * (smc_session()['default_setting']['product_rate'] / 100))+$price;
        }else if(smc_session()['default_setting']['product_rate'] < 0 ){
            $rate_neg =substr(smc_session()['default_setting']['product_rate'],1);
            $price= $price - ($price * ($rate_neg  / 100));
        }
        return $price;
    }

    
    public function addCustomerScertificatee() {
        $logged_id = smc_session()['user_logged_id'];
        $current_date_time = date("Y-m-d H:i:s");

        $this->db->prepare_Stmt('insert into tbl_customers_certificate (customer_id,certificate_info,start_date,end_date,crate_data_time,login_user) 
            values (?,?,?,?,?,?)', [&$this->info['customer_id'], &$this->info['certificate_info'],
            &$this->info['start_date'], &$this->info['end_date'], &$current_date_time, &$logged_id]);
        $error = $this->db->error();
        return $error;
    }

    public function updateCustomerScertificatee() {
        $this->db->prepare_Stmt('update tbl_customers_certificate set customer_id = ?, certificate_info = ?,start_date=?,end_date=?
            where id = ?', [&$this->info['customer_id'], &$this->info['certificate_info'],
            &$this->info['start_date'], &$this->info['end_date'] , &$this->info['id']]);
        $error = $this->db->error();
        return $error;
    }
    public function get_customers_certificate($id) {
        $data = array();
        $query = $this->db->query('select *  from `customerscertificateview`   where id = "' . $id . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $data = $row;
        return $data;
    }
    
    public function deleteCustomersCertificate() {
        $this->db->prepare_Stmt('delete from tbl_customers_certificate where id = ?', [&$this->info['id']]);
        $error = $this->db->error();
        return $error;
    }

    public static function addCustomerContra($data) {
        $logged_id = smc_session()['user_logged_id'];
        $current_date_time = date("Y-m-d H:i:s");
        $db = DBConnectorFactory::loadDriver();
        $file_archive = $_FILES['archive_name'];
        $file_name = !empty($_FILES['archive_name']['name']) ?  (microtime(true) . '.' . pathinfo($_FILES['archive_name']['name'], PATHINFO_EXTENSION)) : '';

        $customer_id = $_POST['customer_id'];
        $contra_info = $_POST['contra_info'];
        $start_date = $_POST['start_date'];
        $end_date = $_POST['end_date'];
        $product_id = $_POST['product_id'];

        $db->prepare_Stmt('insert into tbl_customers_contra (customer_id,contra_info,start_date,end_date,crate_data_time,login_user,product_id,file_name) 
            values (?,?,?,?,?,?,?,?)', [&$customer_id, &$contra_info,
            &$start_date, &$end_date, &$current_date_time, &$logged_id, &$product_id,&$file_name]);
        $error = $db->error();
        if(empty($error)){
            if (!empty($_FILES['archive_name']['name'])) {
                $archive_path = dirBase . "uploads/customer_contra";
                $destination_archive = $archive_path . "/" . $file_name;
                move_uploaded_file($file_archive['tmp_name'], $destination_archive);
            }
        }
        return $error;
    }

    public function get_customers_contra($id) {
        $data = array();
        $query = $this->db->query('select *  from `customerscontraview`   where id = "' . $id . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $data = $row;
        return $data;
    }

    public static function updateCustomerContra($data) {
        $db = DBConnectorFactory::loadDriver();
        $old_archive_name = $_POST['old_archive_name'];
        $file_archive = $_FILES['archive_name'];
        $file_name = $_FILES['archive_name']['name'] != '' ?  (microtime(true) . '.' . pathinfo($_FILES['archive_name']['name'], PATHINFO_EXTENSION)) : $old_archive_name;
        $customer_id = $_POST['customer_id'];
        $contra_info = $_POST['contra_info'];
        $start_date = $_POST['start_date'];
        $end_date = $_POST['end_date'];
        $product_id = $_POST['product_id'];
        $id = $_POST['id'];
         $db->prepare_Stmt('update tbl_customers_contra set customer_id = ?, contra_info = ?,start_date=?,end_date=?,product_id=?,file_name=?
            where id = ?', [&$customer_id, &$contra_info,
            &$start_date, &$end_date , &$product_id, &$file_name , &$id]);
        $error = $db->error();
        if(empty($error)){
            if ($_FILES['archive_name']['name'] != '') {
                $archive_path = dirBase . "uploads/customer_contra";
                $destination_archive = $archive_path . "/" . $file_name;
                move_uploaded_file($file_archive['tmp_name'], $destination_archive);
            }

            if(!empty($old_archive_name) &&  $_FILES['archive_name']['name'] != ''  ){
 
                $del_archive_path = dirBase . "uploads/customer_contra/{$old_archive_name}";
                if (file_exists($del_archive_path))
                    unlink(dirBase . "uploads/customer_contra/{$old_archive_name}");  
            }

        }
        return $error;
    }

    public function deleteCustomersContra() {
        $id = $this->info['id'];
        $query = $this->db->query('select *  from `customerscontraview`   where id = "' . $id . '"');
        $old_archive_name = $this->db->assoc($query)['file_name'];
        if(!empty($old_archive_name)){
            $del_archive_path = dirBase . "uploads/customer_contra/{$old_archive_name}";
            if (file_exists($del_archive_path))
                unlink(dirBase . "uploads/customer_contra/{$old_archive_name}");  
        }


        $this->db->prepare_Stmt('delete from tbl_customers_contra where id = ?', [&$id]);
        $error = $this->db->error();
        return $error;
    }

    public function empty_collected_points() {
        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)');        
        }
       
        $error = $this->db->error();
        return $error;
    } 
    
    public static function add_descriptoin_points($data) {
        $db = DBConnectorFactory::loadDriver();
        $from_point = $_POST['from_point'];
        $to_point = $_POST['to_point'];
        $description = $_POST['description'];

        $db->prepare_Stmt('insert into description_for_point (first_point,last_point,description) 
            values (?,?,?)', [&$from_point, &$to_point, &$description]);
        $error = $db->error();
        return $error;
    }
    
    public function get_point_description($id) {
        $data = array();
        $query = $this->db->query('select *  from `description_for_point`   where id = "' . $id . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $data = $row;
        return $data;
    }

    public function delete_description_points() {
        $this->db->prepare_Stmt('delete from description_for_point where id = ?', [&$this->info['id']]);
        $error = $this->db->error();
        return $error;
    }

    public static function update_description_points($data) {
        $db = DBConnectorFactory::loadDriver();
        $from_point = $_POST['from_point'];
        $to_point = $_POST['to_point'];
        $description = $_POST['description'];
        $id = $_POST['id'];
         $db->prepare_Stmt('update description_for_point set first_point = ?, last_point = ?, description=?
            where id = ?', [&$from_point, &$to_point, &$description, &$id]);
        $error = $db->error();
        return $error;
    }
    
    public function get_customer_points_from_phone($phone) {
        $query = $this->db->query('select collected_points, date_collected_point, Customer_Mobile, Customer_Phone, Customer_Work_Phone from `tbl_customers` where Customer_Mobile = "' . $phone . '" or Customer_Phone = "' . $phone . '" or Customer_Work_Phone = "' . $phone . '"');
        $row = $this->db->assoc($query);
        $row['collected_points'];
        $row['date_collected_point'];
        $row['Customer_Mobile'];
        $row['Customer_Phone'];
        $row['Customer_Work_Phone'];

        $desc_query = $this->db->query('select description from `description_for_point` where "' . $row['collected_points'] . '" between first_point and last_point');
        $desc_row = $this->db->assoc($desc_query);
        $row['description'] = $desc_row['description'];
        return $row;
    } 
    public function ajax_sync_website($id) {

        if($id == 1){
         $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.products (id, brand_id, name,base_price,sku)
        SELECT sp.Product_ID, sp.brand_id, sp.Product_Name , cl.Product_Price , sp.Product_Code
        FROM tbl_stock_products sp
        left join tbl_item_price_by_classes cl on sp.Product_ID = cl.Product_ID and cl.Class_ID = 1
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.products p
            WHERE p.id = sp.Product_ID
        );
         
        ');

        $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.product_stocks (product_id,sku,quantity)
        SELECT sp.Product_ID,  sp.Product_Code,sp.Product_Quantity
        FROM tbl_stock_products sp
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.product_stocks p
            WHERE p.product_id = sp.Product_ID and p.sku = sp.Product_Code
        );
         
        ');

        $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.stock_logs (stock_id,quantity,type)
        SELECT sp.id,  sp.quantity,1
        FROM '.DB_website_NAME.'.product_stocks sp
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.stock_logs p
            WHERE p.stock_id = sp.id  
        );
         
        ');


        $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.categories (id,name)
        SELECT sp.Cat_ID,  sp.Cat_Name 
        FROM tbl_product_cat sp
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.categories p
            WHERE p.id = sp.Cat_ID
        );
         
        ');
        
        $this->db->prepare_Stmt( '
        delete from '.DB_website_NAME.'.products_categories;
        ');


        $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.products_categories (product_id,category_id)
        SELECT sp.Product_ID,  sp.Category_ID 
        FROM tbl_stock_products sp
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.products_categories p
            WHERE p.id = sp.Product_ID and p.category_id = sp.Category_ID 
        );
         
        ');
        $this->db->prepare_Stmt( '
        INSERT INTO '.DB_website_NAME.'.brands (id,name)
        SELECT sp.brand_id,  sp.brand_name 
        FROM tbl_brand_products sp
        WHERE NOT EXISTS (
            SELECT 1
            FROM '.DB_website_NAME.'.brands p
            WHERE p.id = sp.brand_id
        );
         
        ');
        }else if($id == 2){
            $this->db->prepare_Stmt( '
            update '.DB_website_NAME.'.product_stocks p  
            INNER JOIN tbl_stock_products sp ON p.product_id = sp.Product_ID and p.sku = sp.Product_Code
            SET p.quantity = sp.Product_Quantity;
            
            ');
            // $this->db->prepare_Stmt( '
            // update '.DB_website_NAME.'.stock_logs p  
            // INNER JOIN '.DB_website_NAME.'.product_stocks sp ON p.stock_id = sp.id  
            // SET p.quantity = sp.quantity;
            
            // ');
            $this->db->prepare_Stmt( '
            delete from '.DB_website_NAME.'.stock_logs;
            
            ');

            $this->db->prepare_Stmt( '
            INSERT INTO '.DB_website_NAME.'.stock_logs (stock_id,quantity,type)
            SELECT sp.id,  sp.quantity,1
            FROM '.DB_website_NAME.'.product_stocks sp
            WHERE NOT EXISTS (
                SELECT 1
                FROM '.DB_website_NAME.'.stock_logs p
                WHERE p.stock_id = sp.id  
            );
            
            ');


        }else if($id == 3){
            $query = $this->db->query('SELECT * FROM  '.DB_website_NAME.'.orders ');
            while ($row = $this->db->assoc($query)){
                $cheeck_query = $this->db->query('SELECT * FROM   tbl_customers where customer_website_id = '.$row['user_id'].' ');
                $cheack_user_row =$this->db->rowsno($cheeck_query);
                if($cheack_user_row == 0){
                    $query = $this->db->query('SELECT * FROM  '.DB_website_NAME.'.users where id = '.$row['user_id'].' ');
                    $user_row = $this->db->assoc($query);
                    $name = $user_row['firstname'].' '.$user_row['lastname'];
                    $this->db->prepare_Stmt( '
                    INSERT INTO tbl_customers (Customer_Name,Customer_Phone,Customer_Country_ID,Customer_City_ID,Currency_ID,Class_ID,customer_website_id)
                    values ("'.$name.'","'.$user_row['mobile'].'","120","2438","144","1","'.$row['user_id'].'");
                    ');
                    $customer_id = $this->db->id();
                }else{
                    $get_user_row =$this->db->assoc($cheeck_query);
                    $customer_id = $get_user_row['Customer_ID'];
                }

                $cheeck_order_query = $this->db->query('SELECT * FROM   tbl_purchase_order where website_order_id = '.$row['id'].' ');
                $cheack_order_row =$this->db->rowsno($cheeck_order_query);

                if($cheack_order_row == 0){
                    $today = date("Y-m-d");
                    $order_description = "order_number: ".$row['order_number'];
                    $current_date_time = date("Y-m-d H:i:s");
                    $sale_num = self::getMaxOrderForOnline(0, 1, 'B', 0);
                    $current_year_id = SESSION::getCurrentYearID();
                    $this->db->prepare_Stmt( '
                    INSERT INTO tbl_purchase_order (Order_ID_Auto,Supplier_ID,Order_Date,Status_ID,Currency_ID,current_rate,Depot_ID,branch_id,is_sales,is_quotation,sale_due_date,date_time,date_created,sale_prefix,net_total,sub_total,order_description,website_order_id,created_logged_id,Logged_ID,is_actual,current_year_id,Class_ID)
                    values ('.$sale_num.',"'.$customer_id.'","'.$today.'","1","144",1,1,1,1,0,"'.$today.'","'.$current_date_time.'","'.$current_date_time.'","B",'.$row['total_amount'].','.$row['total_amount'].',"'.$order_description.'",'.$row['id'].','.smc_session()['user_logged_id'].','.smc_session()['user_logged_id'].',0,'.$current_year_id.',1);
                    
                    ');
                    $order_id = $this->db->id();
                    $order_query = $this->db->query('SELECT * FROM  '.DB_website_NAME.'.order_details where order_id = '.$row['id'].'  ');
                    while ($det_row = $this->db->assoc($order_query)){

                        $item_query = $this->db->query('SELECT * FROM tbl_stock_products where Product_ID = '.$det_row['product_id'].'  ');
                        $item_row = $this->db->assoc($item_query);
                        $this->db->prepare_Stmt(  '
                        INSERT INTO tbl_purchase_order_details(Order_ID,Item_ID,Quantity,Item_Quantity_Current,UOM_ID,Unit_Price,total_price)
                                                        values("'.$order_id.'","'.$det_row['product_id'].'",'.$det_row['quantity'].','.$det_row['quantity'].','.$item_row['UOM_ID'].','.$det_row['base_price'].','.$det_row['total_price'].')
                        ');
                        
                    }  
                }   
                


            }


        }
        $error = $this->db->error();
        return $error;

    }
    public function getMaxOrderForOnline($is_quotation, $is_sales, $sale_prefix, $is_actual) {
        $query = $this->db->query('SELECT MAX(Order_ID_Auto) AS Entry_ID 
            FROM tbl_purchase_order where  is_quotation = "' . $is_quotation . '"
                and is_sales = "' . $is_sales . '" and sale_prefix = "' . $sale_prefix . '" and is_actual = "' . $is_actual . '"');
        $row = $this->db->assoc($query);
        if (!empty($row))
            $order = $row['Entry_ID'] + 1;
        else
            $order = 1;

        return $order;
    }

   
}
