<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

App::uses('UtilityController', 'Controller');
App::uses('AppController', 'Controller');
App::uses('CakeTime', 'Utility');

/**
 * CakePHP DsrController
 * @author Aether2
 */
class DashboardController extends AppController {
    public $uses = array();
    
    public $components = array('Paginator');
    
    
    public function beforeFilter()
    {
        parent::beforeFilter();
        $this->layout = "dashboard";
        $this->response->disableCache();

        $this->Auth->allow();

        if ($this->Auth->user()) {

            $locations = [];
            $locations[] = $this->Session->read('Auth.User.location_id');
            $storeId = $this->Session->read('Auth.User.location_id');
            $locationsList = $this->Session->read('Auth.User.location_ids'); 
            if (!empty($locationsList)) {
                if (is_array($locationsList)) {
                    $locations = array_merge($locations, $locationsList);
                } else {
                    $locations = array_merge($locations, explode(',', $locationsList));
                }
            }

            $storeIdsArr = array_filter(array_unique($locations)); 
            
            $this->loadModel('Inventory_sku');

            $lowStockSkus = $this->Inventory_sku->getLowStockSkus($storeIdsArr);

            $skuIds = [];
            if (!empty($lowStockSkus)) {
                $skuIds = array_map(function($row) {
                    return (int)$row['l']['sku_id'];
                }, $lowStockSkus);
            }

            $limit = 4;
            $skuMessage = $this->buildLowStockList($lowStockSkus, $limit, 'sku');
            $controller = 'dashboard';

            $this->set(compact('skuMessage', 'skuIds', 'storeId', 'controller'));
        }
    }
    
    
    private function buildLowStockList($data, $limit = 4, $type)
    {
        if (empty($data)) {
            return '';
        }

        $count = count($data);
        $html  = "<ul style='margin:0; padding-left:15px;'>";

        for ($i = 0; $i < min($limit, $count); $i++) {
            $item = $data[$i];
           
            $name = h($item['s']['name']);
            $requiredStock = (float)$item['s']['required_stock'];
            $availableStock = (float)$item['l']['last_balance'];
            
            $html .= "
                <li>
                    <span style='color:red; font-weight:bold;'>{$name}</span>
                    <span> / Required: {$requiredStock}</span>
                    <span> / Available: {$availableStock}</span>
                </li>
            ";
        }

        $html .= "</ul>";

        if ($count > $limit) {
            $html .= "<div style='font-weight:bold; margin-top:4px;'>... more</div>";
        }

        return $html;
    }

    
    public function markAlertViewed() {
        $this->autoRender = false;
        $this->layout = false;
        if ($this->request->is('post')) {
            $type = $this->request->data('type');
            $skuIds = $this->request->data('sku_ids');
            $storeId = $this->request->data('store_id');

            if (empty($skuIds) || empty($storeId)) {
                echo json_encode(['success' => false, 'message' => 'Missing parameters']);
                return;
            }

            try {
                $this->loadModel('Inventory_sku');
                $this->Inventory_sku->markAlertsAsViewed([$storeId], $skuIds);
                
                echo json_encode(['success' => true, 'message' => 'Alerts marked as viewed']);
            } catch (Exception $e) {
                echo json_encode(['success' => false, 'message' => $e->getMessage()]);
            }
        } else {
            echo json_encode(['success' => false, 'message' => 'Invalid request']);
        }
    }

    public function create_pin()
    {
        $sendmessage= new UtilityController;
        
        $this->layout = "login";
        $id=$_REQUEST['id'];
        $this->set(compact('id'));
        
        $carddetail=$this->Card->find('first',array('conditions'=>array('Card.id'=>$id)));
        if(!$carddetail){
            $this->Flash->error(__('Card not found'));
        }
        
        if ($this->request->is(array('post', 'put'))) {
            $id=$this->data['User']['id'];
            $pin = $this->data['User']['pin'];
            $otpnew = $this->data['User']['otp'];
            if($id==''){
                $this->Flash->error(__('ID error'));
            }
            if($pin==''){
                $this->Flash->error(__('Pin could not be Blank'));
            }
            if($otpnew==''){
                $this->Flash->error(__('OTP could not be Blank'));
            }
            $cardotpchk=$this->Card->find('first',array('conditions'=>array('Card.id'=>$id,'Card.otp'=>$otpnew)));
            if(!$cardotpchk){
                $this->Flash->error(__('Wrong OTP'));
                return false;
            }
            
            $pinupdate = $this->Card->query("UPDATE cards SET pin='$pin',otp='0',sync='0',local_sync='0' WHERE id=$id");
            $this->Flash->success(__('Pin has been saved.'));
        }else{
            $name=$carddetail['Card']['name'];
            $mobile=$carddetail['Card']['mobile'];
            $otp = mt_rand(1000, 9999);
            $query=$this->Card->query("UPDATE cards SET otp='$otp',sync='0',local_sync='0' WHERE id = '$id'");
            
            $message = "Hi $name, please use $otp to login to PhyloPay.";
            $msg=$sendmessage->message($message,$mobile);
    //      
        }
        
    }
    
    public function home()
    {
        $this->layout = "users";
    
        // Ensure the user is authenticated
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        // Wallet balance and total active cards
        $cardbal = $this->Card->query("
            SELECT 
                SUM(cardbalance) AS wallet_bal,
                SUM(IF(status IN (2,1), 1, 0)) AS activecard 
            FROM cards
        ");
        $wallet_balance  = $cardbal[0][0]['wallet_bal'] ?? 0;
        $tot_activecards = $cardbal[0][0]['activecard'] ?? 0;
    
        // Total distinct cardtracking users
        $cardtrackingUsers = $this->Cardtracking->query("
            SELECT COUNT(DISTINCT(customerphone)) AS customers 
            FROM cardtracking
        ");
        $totalusers = $cardtrackingUsers[0][0]['customers'] ?? 0;
    
        // Determine date range from request
        // $date = $this->request->data['home']['sdate'] ?? null;
        // $todayDate = date("Y-m-d");
    
        // if ($date == 2) {
        //     $days_ago = date("Y-m-d", strtotime("-30 days"));
        // } elseif ($date == 1) {
        //     $days_ago = date("Y-m-d", strtotime("-7 days"));
        // } else {
        //     $days_ago = $todayDate;
        // }
        
        // $startDatetime = $days_ago . ' ' . shiftstart;
        // $endDatetime   = date('Y-m-d', strtotime($todayDate . ' +1 day')) . ' ' . shiftend;
        
        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $todayDate = date("Y-m-d");

        if ($this->request->is(['post', 'put']) && !empty($this->request->data['daterange'])) 
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }    
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = [];
        $cond = '';
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
        
            // Convert to array safely
            $userLocationIds = is_array($userLocationId)
                ? $userLocationId
                : array_map('trim', explode(',', $userLocationId));
        
            // CakePHP conditions (preferred)
            $conditions['store_id IN'] = $userLocationIds;
        
            // Raw SQL condition (if really needed)
            $cond = "AND store_id IN (" . implode(',', array_map('intval', $userLocationIds)) . ")";
        }
        
        // Open table count
        // $open_tables = $this->Order_table->query("
        //     SELECT COUNT(id) AS open_table 
        //     FROM order_tables 
        //     WHERE status = '2'  
        // ");
        
        // $open_table = $open_tables[0][0]['open_table'] ?? 0;
    
        // // Open table total amount
        // $open_tables_amount = $this->Order_table->query("
        //     SELECT SUM(total_price)+SUM(total_tax) AS open_table 
        //     FROM order_orderhistories 
        //     WHERE reference_id IN (
        //         SELECT reference_id 
        //         FROM order_tables 
        //         WHERE status = '2' 
        //     ) and status!=0
        // ");
        // $open_table_amount = $open_tables_amount[0][0]['open_table'] ?? 0;
        
        
        $open_tables_amount = $this->Order_orderhistory->query("
            SELECT SUM(total_price)+SUM(total_tax) AS open_table_amount,count(DISTINCT(table_number)) as open_table
            FROM order_orderhistories 
            WHERE status = '1' and created BETWEEN '$startDatetime' AND '$endDatetime' $cond
        ");
        
        $open_table_amount = $open_tables_amount[0][0]['open_table_amount'] ?? 0;
        $open_table = $open_tables_amount[0][0]['open_table'] ?? 0;
        
        
        // Card status counts in date range
        $cardStats = $this->Card->query("
            SELECT 
                SUM(IF(status IN (2,1), 1, 0)) AS activecard, 
                SUM(IF(status = 0, 1, 0)) AS inactivecard 
            FROM cards 
            WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
        ");
        $activecards   = $cardStats[0][0]['activecard'] ?? 0;
        $inactivecards = $cardStats[0][0]['inactivecard'] ?? 0;
    
        // Cardtracking financials
        $cardtracking = $this->Cardtracking->query("
            SELECT 
                SUM(IF(type = 1 AND purpose = 'add', amount, 0)) AS totadd,
                SUM(IF(type = 2 AND purpose = 'withdrawal', amount, 0)) AS totused,
                SUM(IF(type = 3, amount, 0)) AS totsec,
                SUM(IF(type = 4, amount, 0)) AS totref,
                COUNT(DISTINCT(customerphone)) AS customers
            FROM cardtracking 
            WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
        ");
        $totaladded    = $cardtracking[0][0]['totadd'] ?? 0;
        $totalused     = $cardtracking[0][0]['totused'] ?? 0;
        $totalsecurity = $cardtracking[0][0]['totsec'] ?? 0;
        $totalrefund   = $cardtracking[0][0]['totref'] ?? 0;
        $users         = $cardtracking[0][0]['customers'] ?? 0;
    
        
        $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price,SUM(pax) AS pax  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $cond and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
        $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $cond");
        
        $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' $cond and total_tax_percentage != 0  AND
            reference_id NOT IN (
                SELECT reference_id 
                FROM order_payments 
                WHERE type = 7 
                  AND status = 2
            )");
        
        $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT sum(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id),2),0)) AS  no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where created BETWEEN '$startDatetime' AND '$endDatetime' $cond and status!=0");
        $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime'  and status=2 $cond and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 )");
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        // Send data to view
        // Last sync time for display
        $lastSyncData = $this->_getLastSyncTimes();
        $lastPushTime = $lastSyncData['push']['time'] ?? 'Never';
        $lastPullTime = $lastSyncData['pull']['time'] ?? 'Never';
        $lastPushBills = $lastSyncData['push']['bills_synced'] ?? 0;
        $lastPushFailed = $lastSyncData['push']['bills_failed'] ?? 0;

        // Send data to view
        $this->set(compact(
            'open_table_amount',
            'open_table',
            'transactions',
            'payments',
            'taxable',
            'discount',
            'wallet_balance',
            'tot_activecards',
            'activecards',
            'inactivecards',
            'totalusers',
            'totaladded',
            'totalused',
            'totalsecurity',
            'totalrefund',
            'users',
            'transactionsubtotal',
            'transactionsnc',
            'lastPushTime',
            'lastPullTime',
            'lastPushBills',
            'lastPushFailed'
        ));
        
        

    }

    public function login() {
        $this->layout = "login";
        $this->set('title', 'Login Page');
    
        // Already logged in?
        if ($this->Session->check('Auth.User') || $this->Session->check('Auth.Location')) {
            if ($this->Session->check('Auth.User')) {
                return $this->redirect(['controller' => 'dashboard', 'action' => 'home']);
            }
            if ($this->Session->check('Auth.Location')) {
                return $this->redirect(['controller' => 'Outlet', 'action' => 'indent']);
            }
        }
    
        if ($this->request->is('post')) {
    
            // ---- 1. Try login with Users table ----
            $this->Auth->authenticate = [
                'Form' => [
                    'userModel' => 'User',
                    'fields'    => ['username' => 'username', 'password' => 'password']
                ]
            ];
            $this->Auth->constructAuthenticate();
    
            if ($this->Auth->login()) {
                $id = $this->Session->read('Auth.User.id');
                $role = $this->Session->read('Auth.User.role');
                if ($role != 'admin') {
                    // Fetch modules
                    $moduless = $this->User_module->query("SELECT GROUP_CONCAT(name) as modulenames FROM user_modules WHERE user_id=$id and status!=0");
                    $modules = $moduless[0][0]['modulenames'];
                    $this->Session->write('Auth.User.modules', $modules);
    
                    // Fetch locations
                    $locations = $this->User_location->query("SELECT GROUP_CONCAT(location_id) as location_ids FROM user_locations WHERE user_id=$id AND status=1");
                    $location_ids = $locations[0][0]['location_ids'];
                    $this->Session->write('Auth.User.location_ids', $location_ids);
                }
    
                return $this->redirect(['controller' => 'dashboard', 'action' => 'home']);
            }
    
            // ---- 2. Try login with Locations table ----
            // Copy posted User[...] data into Location[...] so Auth can check it
            if (!empty($this->request->data['User'])) {
                $this->request->data['Location'] = $this->request->data['User'];
            }
    
            $this->Auth->logout(); // clear previous attempt
            $this->Auth->authenticate = [
                'Form' => [
                    'userModel' => 'Location',
                    'fields'    => ['username' => 'username', 'password' => 'password'],
                    'scope'     => ['Location.type' => 'OUTLET']
                ]
            ];
            $this->Auth->constructAuthenticate();
    
            if ($this->Auth->login()) {
                $location = $this->Auth->user();
                $this->Session->write('Auth.Location', $location);
                return $this->redirect(['controller' => 'Outlet', 'action' => 'indent']);
            }
            
            // ---- 3. Both failed ----
            $this->Flash->error(__('Invalid username or password, try again'));
        }
    }

    public function logout() {
        // Clear CakePHP Auth session
        $this->Auth->logout();
    
        // Manually clear both User & Location sessions
        $this->Session->delete('Auth.User');
        $this->Session->delete('Auth.Location');
    
        // Redirect to login page
        return $this->redirect('/');
    }
   
    public function wallet_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }    

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $card = $this->Card->query("SELECT SUM(IF(status IN (2,1),1,0)) AS activecard, SUM(IF(status=0,1,0)) AS inactivecard FROM cards WHERE created between '$startDatetime' and '$endDatetime'");
        $activecards=$card[0][0]['activecard'];
        $inactivecards=$card[0][0]['inactivecard'];
        
        $cardtracking = $this->Cardtracking->query("SELECT SUM(IF(type=1 and purpose='add',amount,0)) AS totadd, SUM(IF(type=2 and purpose='withdrawal',amount,0)) AS totused, SUM(IF(type=3,amount,0)) AS totsec, SUM(IF(type=4,amount,0)) AS totref,COUNT(DISTINCT(customerphone)) as customers FROM cardtracking WHERE created between '$startDatetime' and '$endDatetime'");
        $totaladded=$cardtracking[0][0]['totadd'];
        $totalused=$cardtracking[0][0]['totused'];
        $totalsecurity=$cardtracking[0][0]['totsec'];
        $totalrefund=$cardtracking[0][0]['totref'];
     
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
    
        $this->set(compact('activecards','inactivecards','totaladded','totalused','totalsecurity','totalrefund'));
    }
    
    public function wallet_reportexport() {
        $date_range= $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate= date('Y-m-d', strtotime($start_date));
        $enddate= date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $card = $this->Card->query("SELECT SUM(IF(status IN (2,1),1,0)) AS activecard, SUM(IF(status=0,1,0)) AS inactivecard FROM cards WHERE created between '$startDatetime' and '$endDatetime'");
        $activecards=$card[0][0]['activecard'];
        $inactivecards=$card[0][0]['inactivecard'];
        
        $cardtracking = $this->Cardtracking->query("SELECT SUM(IF(type=1 and purpose='add',amount,0)) AS totadd, SUM(IF(type=2 and purpose='withdrawal',amount,0)) AS totused, SUM(IF(type=3,amount,0)) AS totsec, SUM(IF(type=4,amount,0)) AS totref,COUNT(DISTINCT(customerphone)) as customers FROM cardtracking WHERE created between '$startDatetime' and '$endDatetime'");
        $totaladded=$cardtracking[0][0]['totadd'];
        $totalused=$cardtracking[0][0]['totused'];
        $totalsecurity=$cardtracking[0][0]['totsec'];
        $totalrefund=$cardtracking[0][0]['totref'];
        
        
        App::import('Vendor', 'PHPExcel/PHPExcel');
           error_reporting(0);
           ini_set('display_errors', TRUE);
           ini_set('display_startup_errors', TRUE);
           if (PHP_SAPI == 'cli')
                die('This example should only be run from a Web Browser');
           $objPHPExcel = new PHPExcel();
           // Set document properties
           $objPHPExcel->getProperties()->setCreator("Aether")
           ->setLastModifiedBy("Aether")
           ->setTitle("Office 2007 XLSX Aether Document")
           ->setSubject("Office 2007 XLSX Aether Document")
           ->setDescription("Aether Export Data File.")
           ->setKeywords("office 2007 openxml php")
           ->setCategory("AetherPos Export Data File");
           // Add some data
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', '   ' .'WALLET REPORT FROM '.$startdate.' TO '.$enddate);
           
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', '   ' .'Card Data');
            
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A4', 'Active Cards');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B4', $activecards);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A5', 'Inactive Cards');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B5', $inactivecards);
            
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A7', '   ' .'Wallet Data');
            
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A8', 'Total Balance Added');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B8', round($totaladded,2));
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A9', 'Total Used Amount');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B9', round($totalused,2));
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A10', 'Refunded Amount');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B10', round($totalrefund,2));
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A11', 'Security Amount');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B11', round($totalsecurity,2));
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A12', 'Net Balance');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B12', round(($totaladded-$totalused),2));
            
            $objPHPExcel->getActiveSheet()->getStyle("A1:B3")->getFont()->setBold(true);
            $objPHPExcel->getActiveSheet()->getStyle("A7:B7")->getFont()->setBold(true);
            $objPHPExcel->getActiveSheet()->mergeCells('A1:B1');
            
            $baseRow = 3;
            $r=1;
        
            $objPHPExcel->getActiveSheet()->setTitle('Export Data');
            $objPHPExcel->setActiveSheetIndex(0);
            header('Content-Type: application/vnd.ms-excel');
            header('Content-Disposition: attachment;filename="'.'WALLET REPORT.xls"');
            header('Cache-Control: max-age=0');
            header('Cache-Control: max-age=1');
            header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
            header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
            header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
            header ('Pragma: public'); // HTTP/1.0
            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
            $objWriter->save('php://output');
            exit;
               
    }
    
    public function wallet_reportpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range=  $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $card = $this->Card->query("SELECT SUM(IF(status IN (1,2),1,0)) AS activecard, SUM(IF(status=0,1,0)) AS inactivecard FROM cards WHERE created between '$startDatetime' and '$endDatetime'");
            $activecards=$card[0][0]['activecard'];
            $inactivecards=$card[0][0]['inactivecard'];
            
            $cardtracking = $this->Cardtracking->query("SELECT SUM(IF(type=1 and purpose='add',amount,0)) AS totadd, SUM(IF(type=2 and purpose='withdrawal',amount,0)) AS totused, SUM(IF(type=3,amount,0)) AS totsec, SUM(IF(type=4,amount,0)) AS totref,COUNT(DISTINCT(customerphone)) as customers FROM cardtracking WHERE created between '$startDatetime' and '$endDatetime'");
            $totaladded=$cardtracking[0][0]['totadd'];
            $totalused=$cardtracking[0][0]['totused'];
            $totalsecurity=$cardtracking[0][0]['totsec'];
            $totalrefund=$cardtracking[0][0]['totref'];
            
            
            $this->set(compact('startdate','enddate','activecards','inactivecards','totaladded','totalused','totalsecurity','totalrefund'));
        }
    }
    
    public function wallet_history() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cards = $this->Card->query("SELECT cards.id,cards.cardnumber,cards.cardbalance,cards.name,cards.mobile,cardtracking.txnid,cardtracking.customername,cardtracking.cashierName,cardtracking.type,cardtracking.amount,cardtracking.payment_mode as mop,cards.created FROM `cards` LEFT JOIN `cardtracking` ON cardtracking.cardnumber = cards.cardnumber where cards.created BETWEEN '$startDatetime' and '$endDatetime' ORDER BY cardtracking.id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('cards'));
    }
    
    public function wallet_historyexport() {
        $date_range= $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate= date('Y-m-d', strtotime($start_date));
        $enddate= date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cards = $this->Card->query("SELECT cards.id,cards.cardnumber,cards.cardbalance,cards.name,cards.mobile,cardtracking.txnid,cardtracking.customername,cardtracking.cashierName,cardtracking.type,cardtracking.amount,cardtracking.payment_mode,cards.created FROM `cards` LEFT JOIN `cardtracking` ON cardtracking.cardnumber = cards.cardnumber where cards.created BETWEEN '$startDatetime' and '$endDatetime'  ORDER BY cardtracking.id desc");
        $datas=array();
        foreach($cards as $card){
            if(isset($card['cardtracking']['txnid'])){
                $datas[]=array(
                    'txnid'=>$card['cardtracking']['txnid'],
                    'cashierName'=>$card['cardtracking']['cashierName'],
                    'cardnumber'=>$card['cards']['cardnumber'],
                    'mobile'=>$card['cards']['mobile'],
                    'name'=>$card['cards']['name'],
                    'type'=>$card['cardtracking']['type'],
                    'payment_mode'=>$card['cardtracking']['payment_mode'],
                    'amount'=>$card['cardtracking']['amount'],
                    'created'=>$card['cards']['created']
                );
            }
        }
        
        App::import('Vendor', 'PHPExcel/PHPExcel');
           error_reporting(0);
           ini_set('display_errors', TRUE);
           ini_set('display_startup_errors', TRUE);
           if (PHP_SAPI == 'cli')
                die('This example should only be run from a Web Browser');
           $objPHPExcel = new PHPExcel();
           // Set document properties
           $objPHPExcel->getProperties()->setCreator("Aether")
           ->setLastModifiedBy("Aether")
           ->setTitle("Office 2007 XLSX Aether Document")
           ->setSubject("Office 2007 XLSX Aether Document")
           ->setDescription("Aether Export Data File.")
           ->setKeywords("office 2007 openxml php")
           ->setCategory("AetherPos Export Data File");
           // Add some data
           $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', '   ' .'WALLET HISTORY FROM '.$startdate.' TO '.$enddate);
           
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', 'SR. NO.');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B3', 'Txn id');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C3', 'Cashier Name');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D3', 'Card Number');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E3', 'Phone');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F3', 'Customer');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G3', 'Type');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H3', 'Payment Mode');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I3', 'Amount');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J3', 'Created');
            $objPHPExcel->getActiveSheet()->getStyle("A1:J3")->getFont()->setBold(true);
            $objPHPExcel->getActiveSheet()->mergeCells('A1:J1');
            
            $baseRow = 3;
            $r=1;
            
            foreach($datas as $dat){
                  
                if($dat['type']==1){
                    $type='credit';
                }elseif($dat['type']==2){
                    $type='debit';
                }elseif($dat['type']==3){
                    $type='security';
                }else{
                    $type='refund';
                }
                
                if($dat['payment_mode']=='card_charge'){
                    $purpose='Card Charge';
                }else{
                    $purpose=$dat['payment_mode'];
                }
                
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.($baseRow + $r),$r);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B'.($baseRow + $r),$dat['txnid']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C'.($baseRow + $r),$dat['cashierName']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D'.($baseRow + $r),$dat['cardnumber']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E'.($baseRow + $r),$dat['mobile']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F'.($baseRow + $r),$dat['name']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G'.($baseRow + $r),$type);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H'.($baseRow + $r),$purpose);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I'.($baseRow + $r),$dat['amount']);
              $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J'.($baseRow + $r),$dat['created']);
                              
                       $r++;
               
            }
            $objPHPExcel->getActiveSheet()->setTitle('Export Data');
            $objPHPExcel->setActiveSheetIndex(0);
            header('Content-Type: application/vnd.ms-excel');
            header('Content-Disposition: attachment;filename="'.'WALLET HISTORY.xls"');
            header('Cache-Control: max-age=0');
            header('Cache-Control: max-age=1');
            header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
            header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
            header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
            header ('Pragma: public'); // HTTP/1.0
            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
            $objWriter->save('php://output');
            exit;
               
    }
    
    public function wallet_historypdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range=  $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $cards = $this->Card->query("SELECT cards.id,cards.cardnumber,cards.cardbalance,cards.name,cards.mobile,cardtracking.txnid,cardtracking.customername,cardtracking.cashierName,cardtracking.type,cardtracking.amount,cardtracking.payment_mode as mop,cards.created FROM `cards` LEFT JOIN `cardtracking` ON cardtracking.cardnumber = cards.cardnumber where cards.created BETWEEN '$startDatetime' and '$endDatetime'  ORDER BY cardtracking.id desc");
            $datas=array();
            foreach($cards as $card){
                if(isset($card['cardtracking']['txnid'])){
                    $datas[]=array(
                        'txnid'=>$card['cardtracking']['txnid'],
                        'cashierName'=>$card['cardtracking']['cashierName'],
                        'cardnumber'=>$card['cards']['cardnumber'],
                        'mobile'=>$card['cards']['mobile'],
                        'name'=>$card['cards']['name'],
                        'type'=>$card['cardtracking']['type'],
                        'payment_mode'=>$card['cardtracking']['mop'],
                        'amount'=>$card['cardtracking']['amount'],
                        'created'=>$card['cards']['created']
                    );
                }
            }
            $this->set(compact('startdate','enddate','datas'));
        }
    }
    
    public function item_sale_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('-7 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $cashier_id = $this->request->data['Search']['cashier'] ?? null;
        $cashierCondition = $cashier_id ? "AND store_id = $cashier_id" : "";
      
        
        // $orderhistories = $this->Order_orderhistory->query("SELECT 
                        // o.product_id,
                        // o.product_name,
                        // o.category_name as subcat_name,
                        // p.unit_name,
                        // p.cat_name as cat_name,
                        // (case 
                            // when p.dish_type = 0 then 'Food' 
                            // when p.dish_type = 1 then 'Beverage' 
                            // when p.dish_type = 2 then 'Liquor' 
                            // when p.dish_type = 3 then 'Others' 
                            // else 'NA' 
                        // end) as dish_type,
                        // SUM(o.quantity) AS totalquantity,
                        // COALESCE(
                            // SUM(o.price * o.quantity * td.discount_percentage / 100),
                            // 0
                        // ) AS totaldiscount,
                        // ROUND(
                            // SUM(
                                // (o.price * o.quantity) 
                                // * (1 - IFNULL(td.discount_percentage, 0) / 100)
                            // ) / SUM(o.quantity),
                            // 2
                        // ) AS final_price
                        // FROM order_orderhistories o
                        // JOIN catalog_product p
                        // ON p.id = o.product_id
                        // AND p.status = 1
                        // LEFT JOIN (
                        // SELECT
                            // orderhistory_id,
                            // MAX(discount_percentage) AS discount_percentage
                        // FROM order_tax
                        // WHERE status = 2
                        // GROUP BY orderhistory_id
                        // ) td
                        // ON td.orderhistory_id = o.id
                        // WHERE o.status = 2
                        // AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
                        // AND o.reference_id IN (
                        // SELECT op.reference_id
                        // FROM order_payments op
                        // WHERE op.type != 7
                            // AND op.status = 2
                            // AND op.store_id = o.store_id
                        // )
                        // $cashierCondition
                        // GROUP BY o.product_id
        // ");
        
        $branchJoin = $cashier_id
    ? "LEFT JOIN catalog_product_branches cpb
           ON cpb.product_id = o.product_id
           AND cpb.status = 1
           AND cpb.location_id = $cashier_id"
    : "LEFT JOIN catalog_product_branches cpb ON 1=0";
        
        $orderhistories = $this->Order_orderhistory->query("
                SELECT 
                    o.product_id,
                    o.product_name,
                    o.category_name as subcat_name,
                    p.unit_name,
                    p.cat_name as cat_name,
                    (case 
                        when p.dish_type = 0 then 'Food' 
                        when p.dish_type = 1 then 'Beverage' 
                        when p.dish_type = 2 then 'Liquor' 
                        when p.dish_type = 3 then 'Others' 
                        else 'NA' 
                    end) as dish_type,
                    SUM(o.quantity) AS totalquantity,
                    COALESCE(
                        SUM(o.price * o.quantity * td.discount_percentage / 100),
                        0
                    ) AS totaldiscount,
                    ROUND(
                        SUM(
                            (o.price * o.quantity) 
                            * (1 - IFNULL(td.discount_percentage, 0) / 100)
                        ) / SUM(o.quantity),
                        2
                    ) AS final_price,
                    COALESCE(cpb.price, p.price) AS selling_price
                FROM order_orderhistories o
                JOIN catalog_product p
                    ON p.id = o.product_id
                    AND p.status = 1
                $branchJoin
                LEFT JOIN (
                    SELECT
                        orderhistory_id,
                        MAX(discount_percentage) AS discount_percentage
                    FROM order_tax
                    WHERE status = 2
                    GROUP BY orderhistory_id
                ) td
                    ON td.orderhistory_id = o.id
                WHERE o.status = 2
                AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
                AND o.reference_id IN (
                    SELECT op.reference_id
                    FROM order_payments op
                    WHERE op.type != 7
                        AND op.status = 2
                        AND op.store_id = o.store_id
                )
                $cashierCondition
                GROUP BY o.product_id");
        
        
        // $ncorderhistories = $this->Order_orderhistory->query("
            // SELECT 
                // o.product_id,
                // o.product_name,
                // o.category_name as subcat_name,
                // p.unit_name,
                // p.cat_name as cat_name,
                // (case 
                    // when p.dish_type = 0 then 'Food' 
                    // when p.dish_type = 1 then 'Beverage' 
                    // when p.dish_type = 2 then 'Liquor' 
                    // when p.dish_type = 3 then 'Others' 
                    // else 'NA' 
                // end) as dish_type,
                // SUM(o.quantity) AS totalquantity,
                // COALESCE(
                    // SUM(o.price * o.quantity * td.discount_percentage / 100),
                    // 0
                // ) AS totaldiscount,
                // ROUND(
                    // SUM(
                        // (o.price * o.quantity) 
                        // * (1 - IFNULL(td.discount_percentage, 0) / 100)
                    // ) / SUM(o.quantity),
                    // 2
                // ) AS final_price
            // FROM order_orderhistories o
            // JOIN catalog_product p
                // ON p.id = o.product_id 
                // AND p.status = 1
            // LEFT JOIN (
                // SELECT
                    // orderhistory_id,
                    // MAX(discount_percentage) AS discount_percentage
                // FROM order_tax
                // WHERE status != 0
                // GROUP BY orderhistory_id
            // ) td
                // ON td.orderhistory_id = o.id
            // WHERE o.status = 2
            // AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
            // AND o.reference_id IN (
                // SELECT op.reference_id
                // FROM order_payments op
                // WHERE op.type = 7
                    // AND op.status = 2
                    // AND op.store_id = o.store_id
            // )
            // $cashierCondition
            // GROUP BY o.product_id
        // ");
        $ncorderhistories = $this->Order_orderhistory->query("
            SELECT 
                o.product_id,
                o.product_name,
                o.category_name as subcat_name,
                p.unit_name,
                p.cat_name as cat_name,
                (case 
                    when p.dish_type = 0 then 'Food' 
                    when p.dish_type = 1 then 'Beverage' 
                    when p.dish_type = 2 then 'Liquor' 
                    when p.dish_type = 3 then 'Others' 
                    else 'NA' 
                end) as dish_type,
                SUM(o.quantity) AS totalquantity,
                COALESCE(
                    SUM(o.price * o.quantity * td.discount_percentage / 100),
                    0
                ) AS totaldiscount,
                ROUND(
                    SUM(
                        (o.price * o.quantity) 
                        * (1 - IFNULL(td.discount_percentage, 0) / 100)
                    ) / SUM(o.quantity),
                    2
                ) AS final_price,
                COALESCE(cpb.price, p.price) AS selling_price
            FROM order_orderhistories o
            JOIN catalog_product p
                ON p.id = o.product_id 
                AND p.status = 1
            $branchJoin
            LEFT JOIN (
                SELECT
                    orderhistory_id,
                    MAX(discount_percentage) AS discount_percentage
                FROM order_tax
                WHERE status != 0
                GROUP BY orderhistory_id
            ) td
                ON td.orderhistory_id = o.id
            WHERE o.status = 2
            AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
            AND o.reference_id IN (
                SELECT op.reference_id
                FROM order_payments op
                WHERE op.type = 7
                    AND op.status = 2
                    AND op.store_id = o.store_id
            )
            $cashierCondition
            GROUP BY o.product_id
        ");
         // echo "<pre/>";
            // print_r($orderhistories);exit;
        $productcosts = [];
        foreach ([true  => $ncorderhistories, false => $orderhistories] as $isNc => $histories) {
            // echo "<pre/>";
            // print_r($histories);exit;
            foreach ($histories as $history) {
                $data = $history['o'];
                $productDetail = $history['p'];
                $calc = $history[0];
                $product_id = $data['product_id'];
                $unit_name = $productDetail['unit_name'];
                $cat_name = $productDetail['cat_name'];
                $quantity = $calc['totalquantity'];
                $totaldiscount = $calc['totaldiscount'];
                $final_price = $calc['final_price'];
                $selling_price = $calc['selling_price'];
                $subproductingcost = 0;
    
                $semifinisheds = $this->Inventory_linking->find('all', [
                    'conditions' => ['parent_id' => $product_id,'parent_type' => 'Product','component_type' => 'Semifinished', 'status' => 1]
                ]);
    
                foreach ($semifinisheds as $semifinished) {
                    $semifinished_id = $semifinished['Inventory_linking']['component_id'];
                    $semifinished_quantity = $semifinished['Inventory_linking']['quantity'];
                    $totalIngCost = 0;
    
                    $ingredients = $this->Inventory_linking->find('all', [
                        'conditions' => ['parent_id' => $semifinished_id,'parent_type' => 'Semifinished','component_type' => 'Sku', 'status' => 1]
                    ]);
    
                    foreach ($ingredients as $ingredient) {
                        $sku_id = $ingredient['Inventory_linking']['component_id'];
                        $sku_quantity = $ingredient['Inventory_linking']['quantity'];
    
                        $startDatetime = $startdate . ' ' . shiftstart;
                        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
                        
                        $stockin = $this->Inventory_purchase_order_item->find('first', [
                            'conditions' => [
                                'created BETWEEN ? AND ?' => [$startDatetime, $endDatetime],
                                'sku_id' => $sku_id,
                                'status' => 3
                            ],
                            'group' => ['sku_id'],
                            'fields' => [
                                'ROUND(SUM(sku_price), 2) AS sku_price',
                                'SUM(stockin_quantity) AS tquantity',
                                'SUM(sku_price * stockin_quantity) AS tamount'
                            ]
                        ]);
                        if (empty($stockin)) {
                            $stockin = $this->Inventory_purchase_order_item->find('first', [
                                'conditions' => ['sku_id' => $sku_id,'status !=' => 0],
                                'order' => ['id DESC'],
                                'fields' => ['sku_price']
                            ]);
                        }
                        $ingcost = !empty($stockin['Inventory_purchase_order_item']['sku_price'])
        ? $stockin['Inventory_purchase_order_item']['sku_price']
        : 0;
                        $totalIngCost += round($ingcost * $sku_quantity, 2);
                    }
    
                    $subproductingcost += round($totalIngCost * $semifinished_quantity, 2);
                }
    
                $unit_cost = round($subproductingcost, 2);
                $total_cost = round($unit_cost * $quantity, 2);
                
                if (!isset($productcosts[$product_id])) {
                    $productcosts[$product_id] = [
                        'product_id' => $product_id,
                        'product_name' => $data['product_name'],
                        'category_name' => $cat_name,
                        'subcat_name' => $data['subcat_name'],
                        'dish_type' => $calc['dish_type'],
                        'unit_name' => $unit_name,
                        'totalquantity' => 0,
                        'final_price' => 0,
                        'selling_price' => $calc['selling_price'],
                        'unit_cost' => 0,
                        'total_cost' => 0,
                        'nctotalquantity' => 0,
                        'ncfinal_price' => 0,
                        'nctotal_cost' => 0,
                        'totaldiscount' => 0,
                    ];
                }
    
                if ($isNc) {
                    $productcosts[$product_id]['nctotalquantity'] += $quantity;
                    $productcosts[$product_id]['ncfinal_price'] += $final_price;
                    $productcosts[$product_id]['nctotal_cost'] += $total_cost;
                    
                } else {
                    $productcosts[$product_id]['totalquantity'] += $quantity;
                    $productcosts[$product_id]['totaldiscount'] += $totaldiscount;
                    $productcosts[$product_id]['final_price'] += $final_price;
                    $productcosts[$product_id]['unit_cost'] = $unit_cost;
                    $productcosts[$product_id]['total_cost'] += $total_cost;
                }
            }
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        
        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);

        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'productcosts', 'orderhistories', 'cashier_id'));
    }
    
    

    public function item_sale_reportexport() {
        $date_range = $_GET['sdate'] ?? '';
        $cashier_id = $_GET['cashier'] ?? null;

        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);

        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashierCondition = $cashier_id ? "AND store_id = $cashier_id" : "";
        
        if($cashier_id){
            $storenames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
            $storename=$storenames['Location']['name'];
        }else{
            $storename='All Stores';
        }
        $branchJoin = $cashier_id
        ? "LEFT JOIN catalog_product_branches cpb
               ON cpb.product_id = o.product_id
               AND cpb.status = 1
               AND cpb.location_id = $cashier_id"
        : "LEFT JOIN catalog_product_branches cpb ON 1=0";

        $orderhistories = $this->Order_orderhistory->query("SELECT 
                        o.product_id,
                        o.product_name,
                        o.category_name as subcat_name,
                        p.unit_name,
                        p.cat_name as cat_name,
                        (case 
                            when p.dish_type = 0 then 'Food' 
                            when p.dish_type = 1 then 'Beverage' 
                            when p.dish_type = 2 then 'Liquor' 
                            when p.dish_type = 3 then 'Others' 
                            else 'NA' 
                        end) as dish_type,
                        SUM(o.quantity) AS totalquantity,
                        COALESCE(
                            SUM(o.price * o.quantity * td.discount_percentage / 100),
                            0
                        ) AS totaldiscount,
                        ROUND(
                            SUM(
                                (o.price * o.quantity) 
                                * (1 - IFNULL(td.discount_percentage, 0) / 100)
                            ) / SUM(o.quantity),
                            2
                        ) AS final_price,
                        COALESCE(cpb.price, p.price) AS selling_price
                        FROM order_orderhistories o
                        JOIN catalog_product p
                        ON p.id = o.product_id
                        AND p.status = 1
                        $branchJoin
                        LEFT JOIN (
                        SELECT
                            orderhistory_id,
                            MAX(discount_percentage) AS discount_percentage
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                        ) td
                        ON td.orderhistory_id = o.id
                        WHERE o.status = 2
                        AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND o.reference_id IN (
                        SELECT op.reference_id
                        FROM order_payments op
                        WHERE op.type != 7
                            AND op.status = 2
                            AND op.store_id = o.store_id
                        )
                        $cashierCondition
                        GROUP BY o.product_id
        ");

         $ncorderhistories = $this->Order_orderhistory->query("
            SELECT 
                o.product_id,
                o.product_name,
                o.category_name as subcat_name,
                p.unit_name,
                p.cat_name as cat_name,
                (case 
                    when p.dish_type = 0 then 'Food' 
                    when p.dish_type = 1 then 'Beverage' 
                    when p.dish_type = 2 then 'Liquor' 
                    when p.dish_type = 3 then 'Others' 
                    else 'NA' 
                end) as dish_type,
                SUM(o.quantity) AS totalquantity,
                COALESCE(
                    SUM(o.price * o.quantity * td.discount_percentage / 100),
                    0
                ) AS totaldiscount,
                ROUND(
                    SUM(
                        (o.price * o.quantity) 
                        * (1 - IFNULL(td.discount_percentage, 0) / 100)
                    ) / SUM(o.quantity),
                    2
                ) AS final_price,
                COALESCE(cpb.price, p.price) AS selling_price
            FROM order_orderhistories o
            JOIN catalog_product p
                ON p.id = o.product_id 
                AND p.status = 1
                $branchJoin
            LEFT JOIN (
                SELECT
                    orderhistory_id,
                    MAX(discount_percentage) AS discount_percentage
                FROM order_tax
                WHERE status != 0
                GROUP BY orderhistory_id
            ) td
                ON td.orderhistory_id = o.id
            WHERE o.status = 2
            AND o.created BETWEEN '$startDatetime' AND '$endDatetime'
            AND o.reference_id IN (
                SELECT op.reference_id
                FROM order_payments op
                WHERE op.type = 7
                    AND op.status = 2
                    AND op.store_id = o.store_id
            )
            $cashierCondition
            GROUP BY o.product_id
        ");

        $productcosts = [];

        foreach ([true => $ncorderhistories, false => $orderhistories] as $isNc => $histories) {
            foreach ($histories as $history) {
                $data = $history['o'];
                $productDetail = $history['p'];
                $calc = $history[0];
                $product_id = $data['product_id'];
                $unit_name = $productDetail['unit_name'];
                $cat_name = $productDetail['cat_name'];
                $quantity = $calc['totalquantity'];
                $totaldiscount = $calc['totaldiscount'];
                $final_price = $calc['final_price'];
                $selling_price = $calc['selling_price'];

                $subproductingcost = 0;

                $semifinisheds = $this->Inventory_linking->find('all', [
                    'conditions' => ['parent_id' => $product_id,'parent_type' => 'Product','component_type' => 'Semifinished', 'status' => 1]
                ]);
                
                foreach ($semifinisheds as $semifinished) {
                    $semifinished_id = $semifinished['Inventory_linking']['component_id'];
                    $semifinished_quantity = $semifinished['Inventory_linking']['quantity'];
                    $totalIngCost = 0;

                    $ingredients = $this->Inventory_linking->find('all', [
                        'conditions' => ['parent_id' => $semifinished_id,'parent_type' => 'Semifinished','component_type' => 'Sku', 'status' => 1]
                    ]);

                    foreach ($ingredients as $ingredient) {
                        $sku_id = $ingredient['Inventory_linking']['component_id'];
                        $sku_quantity = $ingredient['Inventory_linking']['quantity'];

                        $stockin = $this->Inventory_purchase_order_item->find('first', [
                            'conditions' => [
                                'created BETWEEN ? AND ?' => [$startDatetime, $endDatetime],
                                'sku_id' => $sku_id,
                                'status' => 3
                            ],
                            'group' => ['sku_id'],
                            'fields' => [
                                'ROUND(SUM(sku_price), 2) AS sku_price',
                                'SUM(stockin_quantity) AS tquantity',
                                'SUM(sku_price * stockin_quantity) AS tamount'
                            ]
                        ]);

                        if (empty($stockin)) {
                            $stockin = $this->Inventory_purchase_order_item->find('first', [
                                'conditions' => ['sku_id' => $sku_id,'status !=' => 0],
                                'order' => ['id DESC'],
                                'fields' => ['sku_price']
                            ]);
                        }

                        $ingcost = !empty($stockin['Inventory_purchase_order_item']['sku_price'])
                            ? $stockin['Inventory_purchase_order_item']['sku_price']
                            : 0;
                        $totalIngCost += round($ingcost * $sku_quantity, 2);
                    }

                    $subproductingcost += round($totalIngCost * $semifinished_quantity, 2);
                }

                $unit_cost = round($subproductingcost, 2);
                $total_cost = round($unit_cost * $quantity, 2);

                if (!isset($productcosts[$product_id])) {
                    $productcosts[$product_id] = [
                        'product_id' => $product_id,
                        'product_name' => $data['product_name'],
                        'category_name' => $cat_name,
                        'subcat_name' => $data['subcat_name'],
                        'dish_type' => $calc['dish_type'],
                        'unit_name' => $unit_name,
                        'totalquantity' => 0,
                        'final_price' => 0,
                        'selling_price' => $calc['selling_price'],
                        'unit_cost' => 0,
                        'total_cost' => 0,
                        'nctotalquantity' => 0,
                        'ncfinal_price' => 0,
                        'nctotal_cost' => 0,
                        'totaldiscount' => 0,
                        'storename' =>$storename
                    ];
                }

                if ($isNc) {
                    $productcosts[$product_id]['nctotalquantity'] += $quantity;
                    $productcosts[$product_id]['ncfinal_price'] += $final_price;
                    $productcosts[$product_id]['nctotal_cost'] += $total_cost;
                } else {
                    $productcosts[$product_id]['totalquantity'] += $quantity;
                    $productcosts[$product_id]['totaldiscount'] += $totaldiscount;
                    $productcosts[$product_id]['final_price'] += $final_price;
                    $productcosts[$product_id]['unit_cost'] = $unit_cost;
                    $productcosts[$product_id]['total_cost'] += $total_cost;
                }
            }
        }
        
        App::import('Vendor', 'PHPExcel/PHPExcel');

        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("POS Export")
            ->setTitle("Item Sale Report");

        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'ITEM SALE REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:R1');
        $objPHPExcel->getActiveSheet()->getStyle("A1:R1")->getFont()->setBold(true);

        $headers = [
            'SR. NO.','Store Name', 'Item Name', 'Dish Type', 'Category', 'Sub Category', 'Unit', 'Number Sold',
            'Cost Price (CP)', 'Sold Price', 'Selling Price','Non-Comp Qty', 'Net Sales', 
            'Billed Cost', 'Comp Qty', 'NC Amount', 'Amount', 'Comp Amount', 
            'Total Discount', 'NC Cost', 'Contribution %'
        ];

        $col = 'A';
        foreach ($headers as $header) {
            $objPHPExcel->getActiveSheet()->setCellValue($col . '3', $header);
            $col++;
        }

        $objPHPExcel->getActiveSheet()->getStyle("A3:U3")->getFont()->setBold(true);

        $row = 4;
        $sr = 1;

        foreach ($productcosts as $product) {
            $sp = $product['final_price'] ?? 0;
            $ncsp = $product['ncfinal_price'] ?? 0;
            $billed_amount = $product['totalquantity'] * $sp;
            $billed_cost = $product['total_cost'];
            $selling_price = $product['selling_price'];
            $ncbilled_cost = $product['nctotal_cost'];
            $contribution = ($billed_amount > 0) ? round((($billed_amount - $billed_cost) / $billed_amount) * 100, 2) : 0;

            $total_sold = $product['nctotalquantity'] + $product['totalquantity'];
            // $total_amount = $total_sold * $sp;
            $comp_amount = $ncsp * $product['nctotalquantity'];
            $total_amount = $comp_amount + $billed_amount;

            $objPHPExcel->getActiveSheet()->fromArray([
                $sr++,
                $product['storename'],
                $product['product_name'] ?? '',
                $product['dish_type'] ?? '',
                $product['category_name'] ?? '',
                $product['subcat_name'] ?? '',
                $product['unit_name'] ?? '',
                number_format((float)$total_sold, 2),
                number_format((float)($product['unit_cost'] ?? 0), 2),
                number_format((float)$sp, 2),
                number_format((float)$selling_price, 2),
                number_format((float)($product['totalquantity'] ?? 0), 2),
                number_format((float)$billed_amount, 2),
                number_format((float)$billed_cost, 2),
                number_format((float)($product['nctotalquantity'] ?? 0), 2),
                number_format((float)$ncsp, 2),
                number_format((float)$total_amount, 2),
                number_format((float)$comp_amount, 2),
                number_format((float)$product['totaldiscount'], 2),
                number_format((float)$ncbilled_cost, 2),
                number_format((float)$contribution, 2) . '%'
            ], null, 'A' . $row);

            $row++;
        }
        
        $objPHPExcel->getActiveSheet()->setTitle('ItemSaleReport');
        $objPHPExcel->setActiveSheetIndex(0);

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="ITEM_SALE_REPORT.xls"');
        header('Cache-Control: max-age=0');
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    public function discount_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('-7 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashier_id = $this->request->data['Search']['cashier'] ?? null;
        $cashierCondition = $cashier_id ? "AND t.store_id = $cashier_id" : "";
        
        $transactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,
                (
                    SELECT SUM(quantity) 
                    FROM order_orderhistories 
                    WHERE reference_id = t.reference_id AND status = 2
                ) AS quantity,
                SUM(t.discount) AS tdiscount,
                t.orderno,
                t.discount,
                t.price,
                t.discount_type,
                t.discount_type_value,
                t.name,
                t.phone,
                t.address,
                (
                    SELECT remarks 
                    FROM user_tracks 
                    WHERE reference_id = t.reference_id and status!=0 and type='discount_apply'
                    LIMIT 1
                ) AS remarks,
				(
				 SELECT u.username 
				 FROM user_tracks ut
				 LEFT JOIN users u ON u.id = ut.user_id
				 WHERE ut.reference_id = t.reference_id  
				 AND ut.status != 0 LIMIT 1
				) AS managername,
                t.reference_id,
                t.amount,
                (
                    SELECT GROUP_CONCAT(type_value) 
                    FROM order_payments 
                    WHERE reference_id = t.reference_id and status!=0
                ) AS type,
                p.created
            FROM 
                order_transactions t
            INNER JOIN 
                order_payments p ON p.reference_id = t.reference_id
            WHERE 
                p.status = 2 
                AND t.discount != 0 
                AND t.status = 2 
                $cashierCondition
                AND p.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            GROUP BY 
                t.reference_id
        ");
            
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
    
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        // Add location filter for non-admins
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        
        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'transactions'));
    }
        
    
	public function discount_reportexport() {

        $this->autoRender = false;
    
        $date_range = $_GET['sdate'] ?? '';
        $cashier_id = $_GET['cashier'] ?? null;
    
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date   = trim($dates[1]);
    
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate   = date('Y-m-d', strtotime($end_date));
    
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
    
        $cashierCondition = $cashier_id ? "AND t.store_id = $cashier_id" : "";
    
        $transactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashiername,
                (SELECT SUM(quantity) FROM order_orderhistories WHERE reference_id = t.reference_id AND status = 2) AS quantity,
                t.discount,
                t.price,
                t.discount_type,
                t.discount_type_value,
                t.orderno,
                t.name,
                t.phone,
                t.address,
                (SELECT remarks FROM user_tracks WHERE reference_id = t.reference_id AND status!=0 AND type='discount_apply' LIMIT 1) AS remarks,
                t.reference_id,
                t.amount,
                (SELECT GROUP_CONCAT(type_value) FROM order_payments WHERE reference_id = t.reference_id AND status!=0) AS type,
                p.created,
				(
					SELECT u.username 
					FROM user_tracks ut
					LEFT JOIN users u ON u.id = ut.user_id
					WHERE ut.reference_id = t.reference_id 
					AND ut.status != 0
					LIMIT 1
				) AS managername
            FROM 
                order_transactions t
            INNER JOIN 
                order_payments p ON p.reference_id = t.reference_id
            WHERE 
                p.status = 2
                AND t.discount != 0
                AND t.status = 2
                $cashierCondition
                AND p.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            GROUP BY 
                t.reference_id
        ");
    
        App::import('Vendor', 'PHPExcel/PHPExcel');
    
        $objPHPExcel = new PHPExcel();
    
        $objPHPExcel->getProperties()
            ->setCreator("POS Export")
            ->setTitle("Discount Report");
    
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'DISCOUNT REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
    
        $objPHPExcel->getActiveSheet()->mergeCells('A1:N1');
        $objPHPExcel->getActiveSheet()->getStyle("A1:N1")->getFont()->setBold(true);
    
        $headers = [
            'SR. NO.',
            'Bill No',
            'Payment Type',
            'Date',
            'Time',
            'Total Discount',
            'Discount Type',
            'Coupon',
            'Amount',
            'Remarks',
            'Customer Name',
            'Manager Name',
            'Phone',
            'Address',
            'Store Name'
        ];
    
        $col = 'A';
        foreach ($headers as $header) {
            $objPHPExcel->getActiveSheet()->setCellValue($col . '3', $header);
            $col++;
        }
    
        $objPHPExcel->getActiveSheet()->getStyle("A3:O3")->getFont()->setBold(true);
    
        $row = 4;
        $sr = 1;
    
        foreach ($transactions as $tr) {
    
            $t = $tr['t'];
    
            $dtype    = $t['discount_type'] ?? '';
            $price    = $t['price'] ?? 0;
            $discount = $t['discount'] ?? 0;
    
            if ($dtype == '0') {
    
                $discountTypes = 'Coupon';
    
            } elseif ($dtype == '1') {
    
                $rate = $price > 0 ? round(($discount / $price) * 100, 2) : 0;
                $discountTypes = 'Percentage (' . $rate . '%)';
    
            } elseif ($dtype == '2') {
    
                $discountTypes = 'Flat (₹' . number_format($discount, 2) . ')';
    
            } else {
    
                $discountTypes = '-';
            }
    
            $created = $tr['p']['created'] ?? '';
    
            $objPHPExcel->getActiveSheet()->fromArray([
                $sr++,
                $t['orderno'] ?? '',
                $tr[0]['type'] ?? '',
                $created ? date('d-m-Y', strtotime($created)) : '',
                $created ? date('h:i A', strtotime($created)) : '',
                number_format((float)$discount, 2),
                $discountTypes,
                '-',
                number_format((float)($t['amount'] ?? 0), 2),
                $tr[0]['remarks'] ?? '',
                $t['name'] ?? '',
                $tr[0]['managername'] ?? '',
                $t['phone'] ?? '',
                $t['address'] ?? '',
                $tr[0]['cashiername'] ?? ''
            ], null, 'A' . $row);
    
            $row++;
        }
    
        $objPHPExcel->getActiveSheet()->setTitle('DiscountReport');
        $objPHPExcel->setActiveSheetIndex(0);
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="DISCOUNT_REPORT.xls"');
        header('Cache-Control: max-age=0');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
    
        exit;
    }
    
    public function bill_wise_summary() {

        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        /* ===================== DATE RANGE ===================== */

        $startDate = date('m/d/Y', strtotime('-7 days'));
        $endDate   = date('m/d/Y');

        if ($this->request->is('post', 'put')) {

            $daterange  = $this->request->data['daterange'];
            $dates      = explode(" - ", $daterange);

            $start_date = trim($dates[0]);
            $end_date   = trim($dates[1]);

            $startDate  = date('m/d/Y', strtotime($start_date));
            $endDate    = date('m/d/Y', strtotime($end_date));

            $startdate  = date('Y-m-d', strtotime($start_date));
            $enddate    = date('Y-m-d', strtotime($end_date));

        } else {

            $startdate  = date('Y-m-d', strtotime($startDate));
            $enddate    = date('Y-m-d', strtotime($endDate));
        }

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        /* ===================== CASHIER FILTER ===================== */

        $cashier_id        = $this->request->data['Search']['cashier'] ?? null;
        $cashierCondition  = $cashier_id ? " AND t.store_id = $cashier_id" : "";

        /* ===================== SPLIT TRANSACTIONS ===================== */
        $splitTransactions = $this->Order_split_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,

                (
                    SELECT SUM(quantity) 
                    FROM order_split_orderhistories 
                    WHERE reference_id = t.reference_id
                    AND split_reference_id = t.split_reference_id
                    AND store_id = t.store_id
                    AND status != 0
                ) AS quantity,

                t.orderno,
                t.reference_id,
                t.split_reference_id,
                t.discount,
                t.total_tax,
                t.price,
                t.amount,
                t.status,  

                (
                    SELECT GROUP_CONCAT(type_value)
                    FROM order_split_payments
                    WHERE reference_id = t.reference_id
                    AND split_reference_id = t.split_reference_id
                    AND store_id = t.store_id
                    AND status = 2
                ) AS type,

                t.created

            FROM order_split_transactions t

            WHERE t.status = 2
            $cashierCondition

            AND t.split_reference_id NOT IN (
                SELECT split_reference_id
                FROM order_split_payments
                WHERE type = 7
            )

            AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'

            ORDER BY t.id DESC
        ");

        /* ===================== NORMAL TRANSACTIONS ===================== */

        $normalTransactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,

                (
                    SELECT SUM(quantity) 
                    FROM order_orderhistories 
                    WHERE reference_id = t.reference_id
                    AND store_id = t.store_id
                    AND status != 0
                ) AS quantity,

                t.orderno,
                t.reference_id,
                NULL AS split_reference_id,
                t.discount,
                t.total_tax,
                t.price,
                t.amount,
                t.status,  

                (
                    SELECT GROUP_CONCAT(type_value)
                    FROM order_payments
                    WHERE reference_id = t.reference_id
                    AND store_id = t.store_id
                    AND status = 2
                ) AS type,

                t.created

            FROM order_transactions t

            WHERE t.status = 2
            AND t.is_split = 0
            $cashierCondition

            AND t.reference_id NOT IN (
                SELECT reference_id
                FROM order_payments
                WHERE type = 7
            )

            AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'

            ORDER BY t.id DESC
        ");

        /* ===================== MERGE BOTH ===================== */

        $transactions = array_merge($splitTransactions, $normalTransactions);

        /* ===================== SORT LATEST FIRST ===================== */

        usort($transactions, function ($a, $b) {
            return strtotime($b[0]['created']) - strtotime($a[0]['created']);
        });

        /* ===================== LOCATION FILTER FOR DROPDOWN ===================== */

        $authUser        = $this->Session->read('Auth.User');
        $userRole        = $authUser['role'] ?? '';
        $userLocationId  = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];

        if ($userRole !== 'admin' && !empty($userLocationId)) {

            $userLocationIds = is_array($userLocationId)
                ? $userLocationId
                : explode(',', $userLocationId); 

            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);

        /* ===================== PASS TO VIEW ===================== */

        $yourStartDateValue = $startDate . ' - ' . $endDate;

        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'transactions'));
    }
    
    public function bill_wise_summary_export() {
        $this->autoRender = false;

        $date_range = $_GET['sdate'] ?? '';
        $cashier_id = $_GET['cashier'] ?? null;

        $dates      = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date   = trim($dates[1]);

        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate   = date('Y-m-d', strtotime($end_date));

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashierCondition = $cashier_id ? " AND t.store_id = $cashier_id" : "";

        /* ===================== SPLIT TRANSACTIONS ===================== */
        $splitTransactions = $this->Order_split_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,
                (
                    SELECT SUM(quantity) 
                    FROM order_split_orderhistories 
                    WHERE reference_id = t.reference_id
                    AND split_reference_id = t.split_reference_id
                    AND store_id = t.store_id
                    AND status != 0
                ) AS quantity,
                t.orderno,
                t.reference_id,
                t.split_reference_id,
                t.discount,
                t.total_tax,
                t.price,
                t.amount,
                t.status,
                (
                    SELECT GROUP_CONCAT(type_value)
                    FROM order_split_payments
                    WHERE reference_id = t.reference_id
                    AND split_reference_id = t.split_reference_id
                    AND store_id = t.store_id
                    AND status = 2
                ) AS type,
                t.created
            FROM order_split_transactions t
            WHERE t.status = 2
            $cashierCondition
            AND t.split_reference_id NOT IN (
                SELECT split_reference_id FROM order_split_payments WHERE type = 7
            )
            AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            ORDER BY t.id DESC
        ");

        /* ===================== NORMAL TRANSACTIONS ===================== */
        $normalTransactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,
                (
                    SELECT SUM(quantity) 
                    FROM order_orderhistories 
                    WHERE reference_id = t.reference_id
                    AND store_id = t.store_id
                    AND status != 0
                ) AS quantity,
                t.orderno,
                t.reference_id,
                NULL AS split_reference_id,
                t.discount,
                t.total_tax,
                t.price,
                t.amount,
                t.status,
                (
                    SELECT GROUP_CONCAT(type_value)
                    FROM order_payments
                    WHERE reference_id = t.reference_id
                    AND store_id = t.store_id
                    AND status = 2
                ) AS type,
                t.created
            FROM order_transactions t
            WHERE t.status = 2
            AND t.is_split = 0
            $cashierCondition
            AND t.reference_id NOT IN (
                SELECT reference_id FROM order_payments WHERE type = 7
            )
            AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            ORDER BY t.id DESC
        ");

        /* ===================== MERGE & SORT ===================== */
        $transactions = array_merge($splitTransactions, $normalTransactions);

        // ✅ Match view sort exactly — always $tr['t']['created']
        usort($transactions, function ($a, $b) {
            $createdA = $a['t']['created'] ?? '1970-01-01';
            $createdB = $b['t']['created'] ?? '1970-01-01';
            return strtotime($createdB) - strtotime($createdA);
        });

        /* ===================== EXCEL EXPORT ===================== */
        App::import('Vendor', 'PHPExcel/PHPExcel');

        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("POS Export")->setTitle("Bill Wise Report");

        // Title row
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'BILL WISE REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:L1');
        $objPHPExcel->getActiveSheet()->getStyle('A1:L1')->getFont()->setBold(true);

        // Headers
        $headers = [
            'SR. NO.', 'Bill No', 'Store', 'Payment Type',
            'Date', 'Time', 'Item Total', 'Bill Price',
            'Bill Discount', 'Bill Tax', 'Bill Amount', 'Status'
        ];
        $col = 'A';
        foreach ($headers as $header) {
            $objPHPExcel->getActiveSheet()->setCellValue($col . '3', $header);
            $col++;
        }
        $objPHPExcel->getActiveSheet()->getStyle('A3:L3')->getFont()->setBold(true);

        // ✅ Status maps
        $statusMap = [
            0 => 'Cancelled',
            1 => 'Pending',
            2 => 'Completed',
        ];
        $statusColorMap = [
            0 => 'FF0000',  // Red
            1 => 'FF8C00',  // Orange
            2 => '008000',  // Green
        ];

        $row = 4;
        $sr  = 1;

        foreach ($transactions as $tr) {

            // ✅ Exactly matching view — always use $tr['t'] and $tr[0]
            $created     = $tr['t']['created'] ?? '';
            $status      = (int)($tr['t']['status'] ?? 2);
            $statusLabel = $statusMap[$status]      ?? 'Completed';
            $statusColor = $statusColorMap[$status] ?? '008000';

            $objPHPExcel->getActiveSheet()->fromArray([
                $sr++,
                $tr['t']['orderno']   ?? '',
                $tr[0]['cashier']     ?? '',
                $tr[0]['type']        ?? '',
                !empty($created) ? date('d-m-Y', strtotime($created)) : '',
                !empty($created) ? date('h:i A', strtotime($created)) : '',
                number_format((float)($tr[0]['quantity']    ?? 0), 2),
                number_format((float)($tr['t']['price']     ?? 0), 2),
                number_format((float)($tr['t']['discount']  ?? 0), 2),
                number_format((float)($tr['t']['total_tax'] ?? 0), 2),
                number_format((float)($tr['t']['amount']    ?? 0), 2),
                $statusLabel,
            ], null, 'A' . $row);

            // ✅ Color status cell (column L)
            $objPHPExcel->getActiveSheet()
                ->getStyle('L' . $row)
                ->getFont()
                ->setBold(true)
                ->getColor()
                ->setRGB($statusColor);

            $row++;
        }

        $objPHPExcel->getActiveSheet()->setTitle('Billwise');
        $objPHPExcel->setActiveSheetIndex(0);

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Billwise_REPORT.xls"');
        header('Cache-Control: max-age=0');

        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }
    public function hourly_sales() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";
        $startDate = date('m/d/Y');
        $endDate   = date('m/d/Y');

        if ($this->request->is('post', 'put')) {
            $daterange  = $this->request->data['daterange'] ?? '';
            $dates      = explode(" - ", $daterange);
            $start_date = trim($dates[0] ?? $startDate);
            $end_date   = trim($dates[1] ?? $endDate);
            $startDate  = date('m/d/Y', strtotime($start_date));
            $endDate    = date('m/d/Y', strtotime($end_date));
            $startdate  = date('Y-m-d', strtotime($start_date));
            $enddate    = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate   = date('Y-m-d', strtotime($endDate));
        }

        $cashier_id = $this->request->data['Search']['cashier'] ?? null;

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if ($cashier_id) {
            $where_location = " AND store_id = " . (int)$cashier_id;
        } else {
            $where_location = ($userRole != 'admin')
                ? " AND store_id IN (" . $userLocationId . ")"
                : '';
        }

        $noChargeSubquery = "SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location";

        $datearray = [];
        $loopdate  = $startdate;
        while (strtotime($loopdate) <= strtotime($enddate)) {
            $datearray[] = $loopdate;
            $loopdate    = date('Y-m-d', strtotime('+1 day', strtotime($loopdate)));
        }

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $itemArray = [];

        foreach ($datearray as $date) {
            $dayStart = $date . ' ' . shiftstart;
            $dayEnd   = date('Y-m-d', strtotime($date . ' +1 day')) . ' ' . shiftend;

            for ($h = 0; $h < 24; $h++) {
                $hourStr   = str_pad($h, 2, '0', STR_PAD_LEFT);
                $from      = $date . ' ' . $hourStr . ':00:00';
                $to        = $date . ' ' . $hourStr . ':59:59';
                $queryFrom = ($from < $dayStart) ? $dayStart : $from;
                $queryTo   = ($to   > $dayEnd)   ? $dayEnd   : $to;

                if (!isset($itemArray[$h])) {
                    $label         = date('ga', strtotime($from)) . '-' . date('ga', strtotime($from . ' +1 hour'));
                    $itemArray[$h] = [
                        'label'          => $label,
                        'orders'         => 0,
                        'pax'            => 0,
                        'basic_sale'     => 0.0,
                        'discount'       => 0.0,
                        'net_sale'       => 0.0,
                        'tax'            => 0.0,
                        'service_charge' => 0.0,  // ✅ new
                    ];
                }

                if (strtotime($queryFrom) > strtotime($queryTo)) {
                    continue;
                }

                $sql = "
                    SELECT
                        COUNT(DISTINCT CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN reference_id END)                                             AS orders,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN pax END), 0)                                                  AS pax,
                        IFNULL(SUM(price), 0)                                                  AS basic_sale,
                        IFNULL(SUM(IFNULL(discount, 0)), 0)                                    AS discount,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN price - IFNULL(discount, 0) END), 0)                         AS net_sale,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN IFNULL(total_tax, 0) END), 0)                                AS tax,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN IFNULL(servicecharge, 0) END), 0)                            AS service_charge
                    FROM order_transactions
                    WHERE status = 2
                      AND created BETWEEN '$queryFrom' AND '$queryTo'
                      $where_location
                ";

                $result = $this->Order_transaction->query($sql);
                $row    = $result[0][0] ?? [];

                $itemArray[$h]['orders']         += (int)($row['orders']         ?? 0);
                $itemArray[$h]['pax']            += (int)($row['pax']            ?? 0);
                $itemArray[$h]['basic_sale']     += (float)($row['basic_sale']   ?? 0);
                $itemArray[$h]['discount']       += (float)($row['discount']     ?? 0);
                $itemArray[$h]['net_sale']       += (float)($row['net_sale']     ?? 0);
                $itemArray[$h]['tax']            += (float)($row['tax']          ?? 0);
                $itemArray[$h]['service_charge'] += (float)($row['service_charge'] ?? 0);
            }
        }

        ksort($itemArray);

        $shiftSql = "
            SELECT
                COUNT(DISTINCT CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN reference_id END)                                             AS totalinvoice,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN pax END), 0)                                                  AS pax,
                IFNULL(SUM(price), 0)                                                  AS basic_sale,
                IFNULL(SUM(IFNULL(discount, 0)), 0)                                    AS discount,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN price - IFNULL(discount, 0) END), 0)                         AS netsale,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN IFNULL(total_tax, 0) END), 0)                                AS shifttax,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN IFNULL(servicecharge, 0) END), 0)                            AS servicecharge
            FROM order_transactions
            WHERE status = 2
              AND created BETWEEN '$startDatetime' AND '$endDatetime'
              $where_location
        ";

        $shiftResult              = $this->Order_transaction->query($shiftSql);
        $shiftTotals              = $shiftResult[0][0] ?? [];
        // ✅ totalsale now includes service charge
        $shiftTotals['totalsale'] = round(
            (float)($shiftTotals['netsale']      ?? 0) +
            (float)($shiftTotals['shifttax']     ?? 0) +
            (float)($shiftTotals['servicecharge'] ?? 0), 2
        );

        $conditions = ['status' => 1, 'type' => 'Outlet'];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $ids = is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId);
            $conditions['id IN'] = array_map('trim', $ids);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'datearray', 'itemArray', 'shiftTotals'));
    }

    public function hourly_sales_export() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $date_range = $_GET['sdate'] ?? '';
        $dates      = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date   = trim($dates[1] ?? $dates[0]);
        $startdate  = date('Y-m-d', strtotime($start_date));
        $enddate    = date('Y-m-d', strtotime($end_date));
        $cashier_id = $_GET['cashier'] ?? null;

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if ($cashier_id) {
            $where_location = " AND store_id = " . (int)$cashier_id;
        } else {
            $where_location = ($userRole != 'admin')
                ? " AND store_id IN (" . $userLocationId . ")"
                : '';
        }

        $noChargeSubquery = "SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location";

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $datearray = [];
        $loopdate  = $startdate;
        while (strtotime($loopdate) <= strtotime($enddate)) {
            $datearray[] = $loopdate;
            $loopdate    = date('Y-m-d', strtotime('+1 day', strtotime($loopdate)));
        }

        $itemArray = [];

        foreach ($datearray as $date) {
            $dayStart = $date . ' ' . shiftstart;
            $dayEnd   = date('Y-m-d', strtotime($date . ' +1 day')) . ' ' . shiftend;

            for ($h = 0; $h < 24; $h++) {
                $hourStr   = str_pad($h, 2, '0', STR_PAD_LEFT);
                $from      = $date . ' ' . $hourStr . ':00:00';
                $to        = $date . ' ' . $hourStr . ':59:59';
                $queryFrom = ($from < $dayStart) ? $dayStart : $from;
                $queryTo   = ($to   > $dayEnd)   ? $dayEnd   : $to;

                if (!isset($itemArray[$h])) {
                    $label         = date('ga', strtotime($from)) . '-' . date('ga', strtotime($from . ' +1 hour'));
                    $itemArray[$h] = [
                        'label'          => $label,
                        'orders'         => 0,
                        'pax'            => 0,
                        'basic_sale'     => 0.0,
                        'discount'       => 0.0,
                        'net_sale'       => 0.0,
                        'tax'            => 0.0,
                        'service_charge' => 0.0,
                    ];
                }

                if (strtotime($queryFrom) > strtotime($queryTo)) {
                    continue;
                }

                $sql = "
                    SELECT
                        COUNT(DISTINCT CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN reference_id END)                                             AS orders,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN pax END), 0)                                                  AS pax,
                        IFNULL(SUM(price), 0)                                                  AS basic_sale,
                        IFNULL(SUM(IFNULL(discount, 0)), 0)                                    AS discount,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN price - IFNULL(discount, 0) END), 0)                         AS net_sale,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN IFNULL(total_tax, 0) END), 0)                                AS tax,
                        IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                            THEN IFNULL(servicecharge, 0) END), 0)                            AS service_charge
                    FROM order_transactions
                    WHERE status = 2
                      AND created BETWEEN '$queryFrom' AND '$queryTo'
                      $where_location
                ";

                $result = $this->Order_transaction->query($sql);
                $row    = $result[0][0] ?? [];

                $itemArray[$h]['orders']         += (int)($row['orders']           ?? 0);
                $itemArray[$h]['pax']            += (int)($row['pax']              ?? 0);
                $itemArray[$h]['basic_sale']     += (float)($row['basic_sale']     ?? 0);
                $itemArray[$h]['discount']       += (float)($row['discount']       ?? 0);
                $itemArray[$h]['net_sale']       += (float)($row['net_sale']       ?? 0);
                $itemArray[$h]['tax']            += (float)($row['tax']            ?? 0);
                $itemArray[$h]['service_charge'] += (float)($row['service_charge'] ?? 0);
            }
        }

        ksort($itemArray);

        $shiftSql = "
            SELECT
                COUNT(DISTINCT CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN reference_id END)                                             AS totalinvoice,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN pax END), 0)                                                  AS pax,
                IFNULL(SUM(price), 0)                                                  AS basic_sale,
                IFNULL(SUM(IFNULL(discount, 0)), 0)                                    AS discount,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN price - IFNULL(discount, 0) END), 0)                         AS netsale,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN IFNULL(total_tax, 0) END), 0)                                AS shifttax,
                IFNULL(SUM(CASE WHEN reference_id NOT IN ($noChargeSubquery)
                    THEN IFNULL(servicecharge, 0) END), 0)                            AS servicecharge
            FROM order_transactions
            WHERE status = 2
              AND created BETWEEN '$startDatetime' AND '$endDatetime'
              $where_location
        ";

        $shiftResult              = $this->Order_transaction->query($shiftSql);
        $shiftTotals              = $shiftResult[0][0] ?? [];
        $shiftTotals['totalsale'] = round(
            (float)($shiftTotals['netsale']       ?? 0) +
            (float)($shiftTotals['shifttax']      ?? 0) +
            (float)($shiftTotals['servicecharge'] ?? 0), 2
        );

        // ✅ Build Excel
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Hourly Sales Export");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Hourly Sales');

        // ✅ 10 columns now — Service Charge added before Total Sale
        $headers = ['#', 'Time Slot', 'Orders', 'PAX', 'Basic Sale', 'Discount', 'Net Sale', 'Tax', 'Service Charge', 'Total Sale'];
        $sheet->fromArray($headers, null, 'A1');
        $sheet->getStyle('A1:J1')->applyFromArray([
            'font'      => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
            'fill'      => ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => '4472C4']],
            'alignment' => ['horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER],
        ]);

        // Data rows
        $row = 2;
        $idx = 1;
        foreach ($itemArray as $h => $data) {
            $totalSale = round(
                (float)($data['net_sale']       ?? 0) +
                (float)($data['tax']            ?? 0) +
                (float)($data['service_charge'] ?? 0), 2
            );

            $sheet->setCellValueByColumnAndRow(0, $row, $idx++);
            $sheet->setCellValueByColumnAndRow(1, $row, $data['label']);
            $sheet->setCellValueByColumnAndRow(2, $row, (int)$data['orders']);
            $sheet->setCellValueByColumnAndRow(3, $row, (int)$data['pax']);
            $sheet->setCellValueByColumnAndRow(4, $row, round((float)$data['basic_sale'],     2));
            $sheet->setCellValueByColumnAndRow(5, $row, round((float)$data['discount'],       2));
            $sheet->setCellValueByColumnAndRow(6, $row, round((float)$data['net_sale'],       2));
            $sheet->setCellValueByColumnAndRow(7, $row, round((float)$data['tax'],            2));
            $sheet->setCellValueByColumnAndRow(8, $row, round((float)$data['service_charge'], 2));  // ✅
            $sheet->setCellValueByColumnAndRow(9, $row, $totalSale);
            $row++;
        }

        // ✅ Only ONE shift totals row (green) — blue row removed matching view
        $sheet->setCellValueByColumnAndRow(0, $row, 'Shift Totals (Total Sale)');
        $sheet->mergeCellsByColumnAndRow(0, $row, 1, $row);
        $sheet->setCellValueByColumnAndRow(2, $row, (int)($shiftTotals['totalinvoice']  ?? 0));
        $sheet->setCellValueByColumnAndRow(3, $row, (int)($shiftTotals['pax']           ?? 0));
        $sheet->setCellValueByColumnAndRow(4, $row, round((float)($shiftTotals['basic_sale']    ?? 0), 2));
        $sheet->setCellValueByColumnAndRow(5, $row, round((float)($shiftTotals['discount']      ?? 0), 2));
        $sheet->setCellValueByColumnAndRow(6, $row, round((float)($shiftTotals['netsale']       ?? 0), 2));
        $sheet->setCellValueByColumnAndRow(7, $row, round((float)($shiftTotals['shifttax']      ?? 0), 2));
        $sheet->setCellValueByColumnAndRow(8, $row, round((float)($shiftTotals['servicecharge'] ?? 0), 2)); // ✅
        $sheet->setCellValueByColumnAndRow(9, $row, round((float)($shiftTotals['totalsale']     ?? 0), 2));
        $sheet->getStyle('A' . $row . ':J' . $row)->applyFromArray([
            'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
            'fill' => ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => '538135']],
        ]);

        // ✅ Auto-width — now J
        foreach (range('A', 'J') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Hourly_Sales_Report.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }
    
    
    public function bill_cancel() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('0 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashier_id = $this->request->data['Search']['cashier'] ?? null;
        $cashierCondition = $cashier_id ? " and t.store_id = $cashier_id" : "";
    
        $transactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,
                t.orderno,
                t.reference_id,
                t.created,
                (
                    SELECT remarks 
                    FROM user_tracks 
                    WHERE reference_id = t.reference_id and type='unbill'
                    LIMIT 1
                ) AS remarks,
                MAX(t.price) AS price,
                MAX(t.amount) AS amount,
                (
                    SELECT GROUP_CONCAT(type_value) 
                    FROM order_payments 
                    WHERE reference_id = t.reference_id
                ) AS type
            FROM 
                order_transactions t
            WHERE 
                t.status = 0
                $cashierCondition
                AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            GROUP BY 
                t.reference_id
        ");
    
        
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
    
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        // Add location filter for non-admins
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        
        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'transactions'));
    }
    
    public function bill_cancel_export() {
        $date_range = $_GET['sdate'] ?? '';
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
    
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashier_id = $_GET['cashier'] ?? null;
    
        if ($cashier_id) {
            $cashierData = $this->Location->find('first', ['conditions' => ['Location.id' => $cashier_id]]);
            $cashiername = $cashierData['Location']['name'] ?? 'Unknown';
            $cashierCondition = " and t.store_id = " . (int)$cashier_id;
        } else {
            $cashiername = 'All Stores';
            $cashierCondition = '';
        }
    
        $transactions = $this->Order_transaction->query("
            SELECT 
                (SELECT name FROM locations WHERE id = t.store_id) AS cashier,
                t.orderno,
                t.reference_id,
                t.created,
                (
                    SELECT remarks 
                    FROM user_tracks 
                    WHERE reference_id = t.reference_id  and type='unbill'
                    LIMIT 1
                ) AS remarks,
                MAX(t.price) AS price,
                MAX(t.amount) AS amount,
                (
                    SELECT GROUP_CONCAT(type_value) 
                    FROM order_payments 
                    WHERE reference_id = t.reference_id
                ) AS type
            FROM 
                order_transactions t
            WHERE 
                t.status = 0
                $cashierCondition
                AND t.created BETWEEN '{$startDatetime}' AND '{$endDatetime}'
            GROUP BY 
                t.reference_id
        ");
        
        $datas = [];
        foreach ($transactions as $transaction) {
            $t = $transaction;
            
            $datas[] = [
                'bill_no' => $t['t']['orderno'],
                'cashierName' => $t[0]['cashier'],
                'type' => $t[0]['type'],
                'amount' => round($t[0]['amount'], 2),
                'remarks' => $t[0]['remarks'] ?? '',
                'created' => date('d-m-Y h:i A', strtotime($t['t']['created'])),
            ];
        }
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")
            ->setTitle("Cancelled Bills Report")
            ->setDescription("Auto-generated Cancelled Bill Report");
    
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'BILL CANCEL REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
    
        // Column Headers
        $headers = [
            'A3' => 'SR. NO.', 'B3' => 'Bill No', 'C3' => 'Store Name',
            'D3' => 'Payment Type', 'E3' => 'Date', 'F3' => 'Remarks','G3' => 'Amount'
        ];
    
        foreach ($headers as $cell => $value) {
            $objPHPExcel->getActiveSheet()->setCellValue($cell, $value);
        }
    
        $objPHPExcel->getActiveSheet()->mergeCells('A1:G1');
        $objPHPExcel->getActiveSheet()->getStyle('A1:G3')->getFont()->setBold(true);
    
        $baseRow = 3;
        $r = 1;
        foreach ($datas as $dat) {
            $rowNum = $baseRow + $r;
            $objPHPExcel->setActiveSheetIndex(0)
                ->setCellValue("A{$rowNum}", $r)
                ->setCellValue("B{$rowNum}", $dat['bill_no'])
                ->setCellValue("C{$rowNum}", $dat['cashierName'])
                ->setCellValue("D{$rowNum}", $dat['type'])
                ->setCellValue("E{$rowNum}", $dat['amount'])
                ->setCellValue("F{$rowNum}", $dat['remarks'])
                ->setCellValue("G{$rowNum}", $dat['created']);
            $r++;
        }
    
        // Finalize export
        $objPHPExcel->getActiveSheet()->setTitle('Cancelled Bills');
        $objPHPExcel->setActiveSheetIndex(0);
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="BILL_CANCEL_REPORT_' . date('Ymd_His') . '.xls"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }
    
    public function void_order() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('0 days'));
        $endDate = date('m/d/Y');
        $orderhistories = [];
        
        $startdate= date('Y-m-d', strtotime($startDate));
        $enddate= date('Y-m-d', strtotime($endDate));
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
    
            $cashier_id = $this->request->data['Search']['cashier'] ?? null;
            
            $conditions = [
                'Order_orderhistory.status' => 0,
                'Order_orderhistory.created >=' => $startDatetime,
                'Order_orderhistory.created <=' => $endDatetime,
            ];
            
            if (!empty($cashier_id)) {
                $conditions['Order_orderhistory.store_id'] = $cashier_id;
            }
            
            // Join user_tracks on reference_id and user_id
            $joins = [
                [
                    'table' => 'user_tracks',
                    'alias' => 'User_track',
                    'type' => 'LEFT',
                    'conditions' => [
                        'User_track.reference_id = Order_orderhistory.reference_id',
                        "User_track.type IN ('unbill', 'deleteitem', 'void_kot')"
                    ]
                ],
                [
                    'table' => 'users',
                    'alias' => 'ManagerUser',
                    'type' => 'LEFT',
                    'conditions' => [
                        'ManagerUser.id = User_track.user_id'
                    ]
                ],
                [
                    'table' => 'locations',
                    'alias' => 'Location',
                    'type' => 'LEFT',
                    'conditions' => [
                        'Location.id = Order_orderhistory.store_id'
                    ]
                ]
            ];
            
            $orderhistories = $this->Order_orderhistory->find('all', [
                'conditions' => $conditions,
                'joins' => $joins,
                'fields' => [
                    'Order_orderhistory.*',
                    'User_track.*',
                    'ManagerUser.name AS manager_name',
                    'Location.name AS location_name'
                ],
                'order' => ['Order_orderhistory.id' => 'DESC']
            ]);
            
        }
        
        // print_r($orderhistories);exit;
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        // Add location filter for non-admins
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users', 'orderhistories'));
    }
    
    public function void_order_export() {
        $date_range = $_GET['sdate'] ?? '';
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
    
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashier_id = $_GET['cashier'] ?? null;
    
        $conditions = [
            'Order_orderhistory.status' => 0,
            'Order_orderhistory.created >=' => $startDatetime,
            'Order_orderhistory.created <=' => $endDatetime,
        ];
        
        if (!empty($cashier_id)) {
            $conditions['Order_orderhistory.store_id'] = $cashier_id;
        }
        
        // Join user_tracks on reference_id and user_id
        $joins = [
            [
                'table' => 'user_tracks',
                'alias' => 'User_track',
                'type' => 'LEFT',
                'conditions' => [
                    'User_track.reference_id = Order_orderhistory.reference_id',
                    'User_track.type NOT LIKE' => '%disc%'
                ]
            ],
            [
                'table' => 'locations',
                'alias' => 'Location',
                'type' => 'LEFT',
                'conditions' => [
                    'Location.id = Order_orderhistory.store_id'
                ]
            ]
        ];
        
        $transactions = $this->Order_orderhistory->find('all', [
            'conditions' => $conditions,
            'joins' => $joins,
            'fields' => [
                'Order_orderhistory.*',
                'User_track.*',
                'Location.name AS location_name' // 👈 fetch only needed column
            ],
            'order' => ['Order_orderhistory.id' => 'DESC']
        ]);
        
        $datas = [];
        foreach ($transactions as $transaction) {
            $t = $transaction;
     
            $remarks = $t['User_track']['remarks'];
            $jsonCheck = json_decode($remarks, true);
            
            if (json_last_error() !== JSON_ERROR_NONE) {
                $remarks=$remarks;
            }else{
                $remarks='';
            }
        
            $datas[] = [
                'store' => $t['Location']['location_name'],
                'Product' => $t['Order_orderhistory']['product_name'],
                'Quantity' => $t['Order_orderhistory']['quantity'],
                'Price' => $t['Order_orderhistory']['price'],
                'Remarks' => $t['Order_orderhistory']['remarks'],
                'manager_remarks' => $remarks,
                'created' => date('d-m-Y h:i A', strtotime($t['Order_orderhistory']['created'])),
            ];
        }
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")
            ->setTitle("Void Orders Report")
            ->setDescription("Auto-generated Void Orders Report");
    
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A1', 'VOID ORDER REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
    
        // Column Headers
        $headers = [
            'A3' => 'SR. NO.', 'B3' => 'Store', 'C3' => 'Product', 'D3' => 'Quantity',
            'E3' => 'Price', 'F3' => 'Remarks', 'G3' => 'Manager Remarks','H3' => 'Date'
        ];
    
        foreach ($headers as $cell => $value) {
            $objPHPExcel->getActiveSheet()->setCellValue($cell, $value);
        }
    
        $objPHPExcel->getActiveSheet()->mergeCells('A1:H1');
        $objPHPExcel->getActiveSheet()->getStyle('A1:H3')->getFont()->setBold(true);
    
        $baseRow = 3;
        $r = 1;
        foreach ($datas as $dat) {
            $rowNum = $baseRow + $r;
            $objPHPExcel->setActiveSheetIndex(0)
                ->setCellValue("A{$rowNum}", $r)
                ->setCellValue("B{$rowNum}", $dat['store'])
                ->setCellValue("C{$rowNum}", $dat['Product'])
                ->setCellValue("D{$rowNum}", $dat['Quantity'])
                ->setCellValue("E{$rowNum}", $dat['Price'])
                ->setCellValue("F{$rowNum}", $dat['Remarks'])
                ->setCellValue("G{$rowNum}", $dat['manager_remarks'])
                ->setCellValue("H{$rowNum}", $dat['created']);
            $r++;
        }
    
        // Finalize export
        $objPHPExcel->getActiveSheet()->setTitle('Void Order');
        $objPHPExcel->setActiveSheetIndex(0);
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="VOID_ORDER_REPORT_' . date('Ymd_His') . '.xls"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }
    
    public function transaction_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashier_id = $this->request->data['Search']['cashier'];
        } else {
            $cashier_id = null; 
        }
        if($cashier_id){
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));

            $cashiername=$cashiernames['Location']['name'];

            $where_location = " and store_id = " . (int)$cashier_id;
            
            $transactions = $this->Order_transaction->query("SELECT order_transactions.*,(select name from locations where id=order_transactions.store_id) as store_name,(SELECT GROUP_CONCAT(type_value) FROM `order_payments` WHERE reference_id=order_transactions.reference_id and store_id=order_transactions.store_id) as mode  FROM `order_transactions`  WHERE order_transactions.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location /* T12-fix: show ALL transactions (no dedup) to match bill-wise summary */ ORDER BY order_transactions.id DESC");
        }else{
            if($userRole!='admin'){
                $where_location = "AND store_id IN (" . $userLocationId . ")";
            
                $transactions = $this->Order_transaction->query("SELECT order_transactions.*,(select name from locations where id=order_transactions.store_id) as store_name,(SELECT GROUP_CONCAT(type_value) FROM `order_payments` WHERE reference_id=order_transactions.reference_id and store_id=order_transactions.store_id) as mode  FROM `order_transactions`  WHERE order_transactions.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location /* T12-fix: show ALL transactions (no dedup) to match bill-wise summary */ ORDER BY order_transactions.id DESC"); 
            }else{
                $cashiername='All Cashiers';
            
                $transactions = $this->Order_transaction->query("SELECT order_transactions.*,(select name from locations where id=order_transactions.store_id) as store_name,(SELECT GROUP_CONCAT(type_value) FROM `order_payments` WHERE reference_id=order_transactions.reference_id and store_id=order_transactions.store_id) as mode  FROM `order_transactions`  WHERE order_transactions.created BETWEEN '$startDatetime' AND '$endDatetime' /* T12-fix: show ALL transactions (no dedup) to match bill-wise summary */ ORDER BY order_transactions.id DESC");
            }
        }
    
        
        $this->set(compact('cashiername'));
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
        
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        
        $users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);

        $this->set(compact('users'));
        
        $this->set(compact('transactions'));
    }
    
    public function transaction_reportexport() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
    
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
    
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate   = date('Y-m-d', strtotime($end_date));
    
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
    
        $cashier_id = $_GET['cashier'];
    
        if($cashier_id){
    
            $transactions = $this->Order_transaction->query("
                SELECT order_transactions.*,
                (SELECT name FROM locations WHERE id=order_transactions.store_id) AS store_name,
                (SELECT GROUP_CONCAT(type_value)
                    FROM order_payments
                    WHERE reference_id=order_transactions.reference_id
                    AND store_id=order_transactions.store_id) AS mode
                FROM order_transactions
                WHERE order_transactions.created BETWEEN '$startDatetime' AND '$endDatetime'
                AND order_transactions.store_id=$cashier_id
                ORDER BY order_transactions.id DESC
            ");
    
        }else{
    
            $transactions = $this->Order_transaction->query("
                SELECT order_transactions.*,
                (SELECT name FROM locations WHERE id=order_transactions.store_id) AS store_name,
                (SELECT GROUP_CONCAT(type_value)
                    FROM order_payments
                    WHERE reference_id=order_transactions.reference_id
                    AND store_id=order_transactions.store_id) AS mode
                FROM order_transactions
                WHERE order_transactions.created BETWEEN '$startDatetime' AND '$endDatetime'
                ORDER BY order_transactions.id DESC
            ");
        }
    
        $datas=array();
        $i=1;
    
        foreach($transactions as $transaction){
    
            if($transaction['order_transactions']['status']==0){
                $status='Cancelled';
            }elseif($transaction['order_transactions']['status']==1){
                $status='Pending / Unsettled';
            }elseif($transaction['order_transactions']['status']==2){
                $status='Settled';
            }else{
                $status='Unknown';
            }
    
            $datas[]=array(
                'sr'=>$i,
                'txnid'=>$transaction['order_transactions']['reference_id'],
                'bill_no'=>$transaction['order_transactions']['orderno'],
                'store'=>$transaction[0]['store_name'],
                'table_number'=>$transaction['order_transactions']['table_number'],
                'pax'=>$transaction['order_transactions']['pax'],
                'phone'=>$transaction['order_transactions']['phone'],
                'name'=>$transaction['order_transactions']['name'],
                'mode'=>$transaction[0]['mode'],
                'amount'=>round($transaction['order_transactions']['amount'],2),
                'status'=>$status,
                'created'=>$transaction['order_transactions']['created']
            );
    
            $i++;
        }
    
        App::import('Vendor','PHPExcel/PHPExcel');
    
        $objPHPExcel = new PHPExcel();
    
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1','TRANSACTION REPORT FROM '.$startDatetime.' TO '.$endDatetime);
    
        $objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('A3','SR NO')
            ->setCellValue('B3','Transaction ID')
            ->setCellValue('C3','Bill No')
            ->setCellValue('D3','Store')
            ->setCellValue('E3','Table Number')
            ->setCellValue('F3','PAX')
            ->setCellValue('G3','Phone')
            ->setCellValue('H3','Name')
            ->setCellValue('I3','Payment Mode')
            ->setCellValue('J3','Amount')
            ->setCellValue('K3','Status')
            ->setCellValue('L3','Created');
    
        $objPHPExcel->getActiveSheet()->mergeCells('A1:L1');
        $objPHPExcel->getActiveSheet()->getStyle("A1:L3")->getFont()->setBold(true);
    
        $row = 4;
    
        foreach($datas as $data){
    
            $objPHPExcel->setActiveSheetIndex(0)
                ->setCellValue('A'.$row,$data['sr'])
                ->setCellValue('B'.$row,$data['txnid'])
                ->setCellValue('C'.$row,$data['bill_no'])
                ->setCellValue('D'.$row,$data['store'])
                ->setCellValue('E'.$row,$data['table_number'])
                ->setCellValue('F'.$row,$data['pax'])
                ->setCellValue('G'.$row,$data['phone'])
                ->setCellValue('H'.$row,$data['name'])
                ->setCellValue('I'.$row,$data['mode'])
                ->setCellValue('J'.$row,$data['amount'])
                ->setCellValue('K'.$row,$data['status'])
                ->setCellValue('L'.$row,$data['created']);
    
            $row++;
        }
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="TRANSACTION_REPORT.xls"');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel,'Excel5');
        $objWriter->save('php://output');
        exit;
    }
        
    public function transaction_reportpdf() {
    
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
    
        $this->layout="login";
    
        if($this->request->is('post')){
    
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ",$date_range);
    
            $start_date = trim($dates[0]);
            $end_date   = trim($dates[1]);
    
            $startdate = date('Y-m-d',strtotime($start_date));
            $enddate   = date('Y-m-d',strtotime($end_date));
    
            $startDatetime = $startdate.' '.shiftstart;
            $endDatetime   = date('Y-m-d',strtotime($enddate.' +1 day')).' '.shiftend;
    
            $cashier_id = $this->request->data['cashier'];
    
            if($cashier_id){
    
                $transactions = $this->Order_transaction->query("
                    SELECT order_transactions.*,
                    (SELECT name FROM locations WHERE id=order_transactions.store_id) AS store_name,
                    (SELECT GROUP_CONCAT(type_value)
                        FROM order_payments
                        WHERE reference_id=order_transactions.reference_id
                        AND store_id=order_transactions.store_id) AS mode
                    FROM order_transactions
                    WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
                    AND store_id=$cashier_id
                    ORDER BY id DESC
                ");
    
            }else{
    
                $transactions = $this->Order_transaction->query("
                    SELECT order_transactions.*,
                    (SELECT name FROM locations WHERE id=order_transactions.store_id) AS store_name,
                    (SELECT GROUP_CONCAT(type_value)
                        FROM order_payments
                        WHERE reference_id=order_transactions.reference_id
                        AND store_id=order_transactions.store_id) AS mode
                    FROM order_transactions
                    WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
                    ORDER BY id DESC
                ");
            }
    
            $datas=array();
    
            foreach($transactions as $transaction){
    
                if($transaction['order_transactions']['status']==0){
                    $status='Cancelled';
                }elseif($transaction['order_transactions']['status']==1){
                    $status='Pending / Unsettled';
                }elseif($transaction['order_transactions']['status']==2){
                    $status='Settled';
                }else{
                    $status='Unknown';
                }
    
                $datas[]=array(
                    'txnid'=>$transaction['order_transactions']['reference_id'],
                    'bill_no'=>$transaction['order_transactions']['orderno'],
                    'store'=>$transaction[0]['store_name'],
                    'table_number'=>$transaction['order_transactions']['table_number'],
                    'pax'=>$transaction['order_transactions']['pax'],
                    'phone'=>$transaction['order_transactions']['phone'],
                    'name'=>$transaction['order_transactions']['name'],
                    'mode'=>$transaction[0]['mode'],
                    'amount'=>round($transaction['order_transactions']['amount'],2),
                    'status'=>$status,
                    'created'=>$transaction['order_transactions']['created']
                );
            }
    
            $this->set(compact('datas','startDatetime','endDatetime'));
        }
    }
    
    public function item_sale_reportpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range=  $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
            
            $cashier_id=  $this->request->data['cashier'];
            if($cashier_id){
                $orderhistories = $this->Order_orderhistory->query("SELECT product_id,product_name,category_name,SUM(quantity) as totalquantity,price FROM `order_orderhistories` WHERE status=2 and created between '$startDatetime' and '$endDatetime' and store_id=$cashier_id GROUP BY product_id");
            }else{
                $orderhistories = $this->Order_orderhistory->query("SELECT product_id,product_name,category_name,SUM(quantity) as totalquantity,price FROM `order_orderhistories` WHERE status=2 and created between '$startDatetime' and '$endDatetime' GROUP BY product_id");            
            }
            $datas=array();
            foreach($orderhistories as $orderhistory){
                $datas[]=array(
                    'product_id'=>$orderhistory['order_orderhistories']['product_id'],
                    'product_name'=>$orderhistory['order_orderhistories']['product_name'],
                    'category_name'=>$orderhistory['order_orderhistories']['category_name'],
                    'totalquantity'=>$orderhistory[0]['totalquantity'],
                    'price'=>$orderhistory['order_orderhistories']['price']
                );
            }
            
            $this->set(compact('startdate','enddate','datas'));
        }
    }
    
    /*
    public function dsr_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('0 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        if (!empty($this->request->data['Search']['cashier'])) {
            $loc_id = $this->request->data['Search']['cashier'];
        } else {
            $loc_id = 0; 
        }
        
        if($loc_id){
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$loc_id)));

            $cashiername=$cashiernames['Location']['name'];

            $where_location="";
            $where_location = " and store_id = " . (int)$loc_id;
            
            $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT sum(total_tax) from order_transactions WHERE status=2 and reference_id=order_payments.reference_id and store_id=order_payments.store_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT 
                    type_value,
                    SUM(amount) AS total_amount
                FROM order_payments
                WHERE 
                    type = 11 and
                     status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                GROUP BY type_value
            ");
            
            $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
            $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id ");
            
            $net_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
                        $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
            ");

            
            $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
        }else{
            $cashiername='All Stores';
            if($userRole!='admin'){
                
                $where_location = "AND store_id IN (" . $userLocationId . ")";
            
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status=2 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location ) $where_location GROUP by tax_id ");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            }else{
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE  status=2 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' ");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)) and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");

                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            }
        }
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
    
        $users=$this->Location->find('all',array('conditions'=>$conditions));
        
        $this->set(compact('users'));
        
        // Last sync time for DSR
        $lastSyncData = $this->_getLastSyncTimes();
        $lastPushTime = $lastSyncData['push']['time'] ?? 'Never';
        $lastPullTime = $lastSyncData['pull']['time'] ?? 'Never';
        $lastPushBills = $lastSyncData['push']['bills_synced'] ?? 0;
        $lastPushFailed = $lastSyncData['push']['bills_failed'] ?? 0;

        $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','net_amount_query','taxable','nontaxable','lastPushTime','lastPullTime','lastPushBills','lastPushFailed'));
       // $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','net_amount_query','taxable','nontaxable'));
    }
   
    // =====================================================
    // EXPORT FUNCTION - MATCHES VIEW CALCULATIONS
    // =====================================================
    public function dsr_reportexport() { 
        $date_range = isset($_GET['sdate']) ? $_GET['sdate'] : '';
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $cashier_id = isset($_GET['cashier']) ? $_GET['cashier'] : '';
        $cashiername = 'All Stores';

        if ($cashier_id) {
            $cashiernames = $this->Location->find('first', array('conditions' => array('id' => $cashier_id)));
            $cashiername = $cashiernames['Location']['name'];
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $datas = array();
        
        $allTaxTypes = [];
        $allSalesTypes = [];
        $allonlinepayTypes = [];
        $alldishSalesTypes = [];
        $ncallSalesTypes = [];

        // FIXED: Define shift times
        $shiftstart = shiftstart;
        $shiftend =shiftend;

        $period = new DatePeriod(
            new DateTime($startdate),
            new DateInterval('P1D'),
            (new DateTime($enddate))->modify('+1 day')
        );

        $dishTypeMap = [
            0 => 'Food',
            1 => 'Beverage',
            2 => 'Liquor',
            3 => 'Others'
        ];
        
        foreach ($period as $dateObj) {
            $day = $dateObj->format('Y-m-d');
            
            $dayStart = $day . ' ' . $shiftstart;
            $dayEnd = date('Y-m-d', strtotime($day . ' +1 day')) . ' ' . $shiftend;

            if($userRole != 'admin') {
                $cashierFilter = $cashier_id ? " AND store_id=$cashier_id" : " AND store_id IN (" . $userLocationId . ")";
            } else {
                $cashierFilter = $cashier_id ? " AND store_id=$cashier_id" : '';
            }
            
            // FIXED: Payment query - total_amount excludes no_charge (type=7) - SAME AS VIEW
            $payments = $this->Order_payment->query("
                SELECT 
                    SUM(IF(type!=7, amount, 0)) AS total_amount,
                    SUM(IF(type=1, amount, 0)) AS cash,
                    SUM(IF(type=10, amount, 0)) AS hold,
                    SUM(IF(type=2, amount, 0)) AS card,
                    SUM(IF(type=6, amount, 0)) AS upi,
                    SUM(IF(type=9, amount, 0)) AS online,
                    SUM(IF(type=7, amount, 0)) AS no_charge_with_tax,
                    SUM(IF(type=7, amount - COALESCE((SELECT SUM(total_tax) FROM order_transactions WHERE status=2 AND reference_id=order_payments.reference_id $cashierFilter), 0), 0)) AS no_charge,
                    SUM(IF(type=8, amount, 0)) AS storecard 
                FROM order_payments
                WHERE status=2 AND created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
            ");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT type_value, SUM(amount) AS total_amount
                FROM order_payments
                WHERE type = 11 AND status = 2 AND created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                GROUP BY type_value
            ");
            
            foreach ($onlinepayments as $op) {
                $key = $op['order_payments']['type_value'];
                $allonlinepayTypes[$key] = true;
            }

            $transactions = $this->Order_transaction->query("
                SELECT COUNT(id) as total_count, SUM(pax) AS pax, SUM(total_tax) AS total_tax,
                    SUM(servicecharge) AS servicecharge, SUM(discount) AS discount,
                    SUM(delivery_charge) AS delivery_charge, SUM(packing_charge) AS packing_charge,
                    SUM(amount) AS amount, SUM(price) AS price, SUM(round) AS roundamount
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter 
                AND reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type=7 AND status=2 $cashierFilter)
            ");
     
            $transactionsnc = $this->Order_transaction->query("
                SELECT SUM(total_tax) AS total_tax
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter 
                AND reference_id IN (SELECT reference_id FROM order_payments WHERE type=7 AND status=2 $cashierFilter)
            ");
     
            $transactionsubtotal = $this->Order_transaction->query("
                SELECT SUM(price) AS price, SUM(discount) AS discount 
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter
            ");

            $taxes = $this->Order_tax->query("
                SELECT tax_id, tax_name, tax_percentage, SUM(tax_value) as tax_value 
                FROM order_tax 
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter 
                AND reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type=7 AND status=2 $cashierFilter)  
                GROUP BY tax_id
            ");
            foreach ($taxes as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $allTaxTypes[$key] = true;
            }

            $net_amount_query = $this->Order_transaction->query("
                SELECT ROUND(SUM(price) - COALESCE(SUM(discount), 0), 2) AS net_amount
                FROM order_transactions ot
                WHERE ot.status = 2 AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                AND ot.reference_id NOT IN (
                    SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter
                )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT ROUND(SUM(price) - COALESCE(SUM(discount), 0), 2) AS net_amount
                FROM order_transactions ot
                WHERE ot.status = 2 AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                AND ot.reference_id IN (
                    SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter
                )
            ");

            $dish_sales = $this->Order_orderhistory->query("
                SELECT cp.dish_type, SUM(ooh.quantity) AS total_qty, ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                INNER JOIN (
                    SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                    FROM order_tax WHERE status != 0 GROUP BY orderhistory_id
                ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                WHERE ooh.created BETWEEN '$dayStart' AND '$dayEnd' AND ooh.status = 2 $cashierFilter
                AND ooh.reference_id NOT IN (
                    SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter
                )
                GROUP BY cp.dish_type ORDER BY cp.dish_type DESC
            ");
            
            foreach ($dish_sales as $ds) {
                $type = $ds['cp']['dish_type'];
                $alldishSalesTypes[$type] = true;
            }
            
            $taxable = $this->Order_orderhistory->query("
                SELECT SUM(total_price) as total_taxable FROM order_orderhistories 
                WHERE status = 2 AND created BETWEEN '$dayStart' AND '$dayEnd' 
                AND total_tax_percentage != 0 $cashierFilter 
                AND reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
            ");
            
            $nontaxable = $this->Order_orderhistory->query("
                SELECT SUM(total_price) as total_nontaxable FROM order_orderhistories 
                WHERE status = 2 AND created BETWEEN '$dayStart' AND '$dayEnd' 
                AND total_tax_percentage = 0 $cashierFilter 
                AND reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
            ");
            
            $nctaxable = $this->Order_orderhistory->query("
                SELECT SUM(total_price) as total_taxable FROM order_orderhistories 
                WHERE status = 2 AND created BETWEEN '$dayStart' AND '$dayEnd' 
                AND total_tax_percentage != 0 $cashierFilter 
                AND reference_id IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
            ");
            
            $ncnontaxable = $this->Order_orderhistory->query("
                SELECT SUM(total_price) as total_nontaxable FROM order_orderhistories 
                WHERE status = 2 AND created BETWEEN '$dayStart' AND '$dayEnd' 
                AND total_tax_percentage = 0 $cashierFilter 
                AND reference_id IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
            ");
            
            $sales = $this->Order_tax->query("
                SELECT kds, kds_name, value, tax_percentage FROM (
                    SELECT SUM(tax_percentage) as tax_percentage, kds, kds_name, ROUND(taxable_price, 2) as value FROM (
                        SELECT tax_percentage, tax_id, kds,
                            (SELECT name FROM pos_printers WHERE kds = order_tax.kds) AS kds_name,
                            ROUND(SUM(taxable_price), 2) AS taxable_price, SUM(tax_value) AS tax_value 
                        FROM order_tax 
                        WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 
                        AND reference_id IN (
                            SELECT reference_id FROM order_orderhistories 
                            WHERE status!=0 AND reference_id NOT IN (
                                SELECT reference_id FROM order_payments WHERE type=7 AND status=2 $cashierFilter
                            ) $cashierFilter
                        ) $cashierFilter GROUP BY kds, tax_id
                    ) AS sub GROUP BY kds, tax_value
                ) AS final GROUP BY kds, tax_percentage
            ");
            foreach ($sales as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $allSalesTypes[$key] = true;
            }
            
            $ncsales = $this->Order_tax->query("
                SELECT kds, kds_name, value, tax_percentage FROM (
                    SELECT SUM(tax_percentage) as tax_percentage, kds, kds_name, ROUND(taxable_price, 2) as value FROM (
                        SELECT tax_percentage, tax_id, kds,
                            (SELECT name FROM pos_printers WHERE kds = order_tax.kds) AS kds_name,
                            ROUND(SUM(taxable_price), 2) AS taxable_price, SUM(tax_value) AS tax_value 
                        FROM order_tax 
                        WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 
                        AND reference_id IN (
                            SELECT reference_id FROM order_orderhistories 
                            WHERE status!=0 AND reference_id IN (
                                SELECT reference_id FROM order_payments WHERE type=7 AND status=2 $cashierFilter
                            ) $cashierFilter
                        ) $cashierFilter GROUP BY kds, tax_id
                    ) AS sub GROUP BY kds, tax_value
                ) AS final GROUP BY kds, tax_percentage
            ");
            foreach ($ncsales as $s) {
                $key = 'NC - ' . $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncallSalesTypes[$key] = true;
            }
            
            // FIXED: Now using total_amount directly (already excludes no_charge) - SAME AS VIEW
            $datas[] = array(
                'date' => $day,
                'cashier' => $cashiername,
                // FIXED: Now uses total_amount directly (excludes no_charge in SQL)
                'total_collection' => round($payments[0][0]['total_amount'], 2),
                'cash' => round($payments[0][0]['cash'], 2),
                'card' => round($payments[0][0]['card'], 2),
                'online' => round($payments[0][0]['online'], 2),
                'online_payments' => $onlinepayments,
                'upi' => round($payments[0][0]['upi'], 2),
                'hold' => round($payments[0][0]['hold'], 2),
                'storecard' => round($payments[0][0]['storecard'], 2),
                'no_charge' => round($payments[0][0]['no_charge'], 2),
                'no_charge_with_tax' => round($payments[0][0]['no_charge_with_tax'], 2),
                'subtotal' => round($transactionsubtotal[0][0]['price'], 2),
                'discount' => round($transactionsubtotal[0][0]['discount'], 2),
                'taxable_amount' => round($taxable[0][0]['total_taxable'] - $transactionsubtotal[0][0]['discount'], 2),
                'nontaxable_amount' => round($nontaxable[0][0]['total_nontaxable'], 2),
                'nctaxable_amount' => round($nctaxable[0][0]['total_taxable'], 2),
                'ncnontaxable_amount' => round($ncnontaxable[0][0]['total_nontaxable'], 2),
                'service_charge' => round($transactions[0][0]['servicecharge'], 2),
                'delivery_charge' => round($transactions[0][0]['delivery_charge'], 2),
                'packing_charge' => round($transactions[0][0]['packing_charge'], 2),
                'total_tax' => round($transactions[0][0]['total_tax'], 2),
                'nctotal_tax' => round($transactionsnc[0][0]['total_tax'], 2),
                'bill_count' => round($transactions[0][0]['total_count'], 2),
                'net_amount' => round($transactions[0][0]['amount'], 2),
                'round' => $transactions[0][0]['roundamount'],
                'taxes' => $taxes,
                'sales' => $sales,
                'ncsales' => $ncsales,
                'dish_sales' => $dish_sales,
                'net_sale' => round($net_amount_query[0][0]['net_amount'], 2),
                'ncnet_sale' => round($ncnet_amount_query[0][0]['net_amount'], 2),
                'pax' => $transactions[0][0]['pax']
            );
        }
            
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("DSR Report Export");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('DSR Report');
        
        $taxColumns = array_keys($allTaxTypes);
        $salesColumns = array_keys($allSalesTypes);
        $ncsalesColumns = array_keys($ncallSalesTypes);
        
        sort($taxColumns);
        sort($salesColumns);
        sort($ncsalesColumns);
        
        $dishsalesColumns = [];
        foreach (array_keys($alldishSalesTypes) as $type) {
            $dishsalesColumns[] = $dishTypeMap[$type] ?? $type;
        }
        sort($dishsalesColumns);
        
        $online_payments = array_keys($allonlinepayTypes);
        sort($online_payments);
        
        // MATCHING VIEW COLUMNS ORDER
        $baseHeaders = ['Date', 'Store', 'Total Collection', 'Cash', 'Card', 'Upi', 'Online'];
        
        $afterOnlineHeaders = [
            'Storecard', 'Hold Bill', 'No Charge', 'No Charge With Tax',
            'Subtotal', 'Discount', 'Taxable', 'Non Taxable',
            'NC Taxable', 'NC Non Taxable', 'NC Net Sale', 'NC Total Tax',
            'Service', 'Delivery', 'Packing', 'Net Sale', 'Total Tax', 'Final Amount',
            'Round', 'Bill Count', 'PAX'
        ];
        
        $headers = array_merge(
            $baseHeaders,
            $online_payments,
            $afterOnlineHeaders,
            $taxColumns,
            $salesColumns,
            $ncsalesColumns,
            $dishsalesColumns
        );
        
        $sheet->fromArray($headers, null, 'A1');
        
        $row = 2;
        foreach ($datas as $data) {
            $colIndex = 0;

            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['date']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['cashier']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['total_collection']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['cash']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['card']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['upi']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['online']);
            
            $onlinepaymentValues = array_fill_keys($online_payments, 0);
            foreach ($data['online_payments'] as $t) {
                $key = $t['order_payments']['type_value'];
                $onlinepaymentValues[$key] = round($t[0]['total_amount'], 2);
            }
            
            foreach ($online_payments as $op) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $onlinepaymentValues[$op]);
            }
            
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['storecard']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['hold']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['no_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['no_charge_with_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['subtotal']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['discount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['taxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['nontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['nctaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['ncnontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['ncnet_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['nctotal_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['service_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['delivery_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['packing_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['net_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['total_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['net_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['round']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['bill_count']);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $data['pax']);
            
            $taxValues = array_fill_keys($taxColumns, 0);
            foreach ($data['taxes'] as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $taxValues[$key] = round($t['0']['tax_value'], 2);
            }
            
            foreach ($taxColumns as $taxCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $taxValues[$taxCol]);
            }

            $salesValues = array_fill_keys($salesColumns, 0);
            foreach ($data['sales'] as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $salesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($salesColumns as $salesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $salesValues[$salesCol]);
            }
            
            $ncsalesValues = array_fill_keys($ncsalesColumns, 0);
            foreach ($data['ncsales'] as $s) {
                $key = 'NC - ' . $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncsalesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($ncsalesColumns as $ncsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $ncsalesValues[$ncsalesCol]);
            }
            
            $dishsalesValues = array_fill_keys($dishsalesColumns, 0);
            
            foreach ($data['dish_sales'] as $ds) {
                if (!isset($ds['cp']['dish_type'])) {
                    continue;
                }
                $type = (int)$ds['cp']['dish_type'];
                $key = $dishTypeMap[$type] ?? $type;
                if (array_key_exists($key, $dishsalesValues)) {
                    $dishsalesValues[$key] = round((float)$ds[0]['total_amount'], 2);
                }
            }

            foreach ($dishsalesColumns as $dishsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $dishsalesValues[$dishsalesCol]);
            }

            $row++;
        }
        
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="DSR_REPORT.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }
    public function dsr_reportpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range= $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $cashier_id=$this->request->data['cashier'];
            if($cashier_id){
                $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
                $cashiername=$cashiernames['Location']['name'];

                $where_location=" and store_id=$cashier_id";
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status=2 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
            
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
    
                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");
                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
            }else{
                $cashiername='All Stores';
                if($userRole!='admin' ){
                    $where_location=" AND store_id IN (" . $userLocationId . ")";
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                    
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
    
                                        $dish_sales = $this->Order_orderhistory->query("
                            SELECT
                                cp.dish_type,
                                SUM(ooh.quantity) AS total_qty,
                                ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                            FROM order_orderhistories ooh
                            INNER JOIN catalog_product cp
                                ON cp.id = ooh.product_id
                            INNER JOIN (
                                SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                                FROM order_tax
                                WHERE status != 0
                                GROUP BY orderhistory_id
                            ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                            WHERE
                                ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                                AND ooh.status = 2 $where_location
                                AND ooh.reference_id NOT IN (
                                    SELECT reference_id
                                    FROM order_payments
                                    WHERE type = 7
                                      AND status = 2 $where_location
                                )
                            GROUP BY cp.dish_type
                            ORDER BY cp.dish_type DESC
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                }else{
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status=2 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' ");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
    
                                        $dish_sales = $this->Order_orderhistory->query("
                            SELECT
                                cp.dish_type,
                                SUM(ooh.quantity) AS total_qty,
                                ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                            FROM order_orderhistories ooh
                            INNER JOIN catalog_product cp
                                ON cp.id = ooh.product_id
                            INNER JOIN (
                                SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                                FROM order_tax
                                WHERE status != 0
                                GROUP BY orderhistory_id
                            ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                            WHERE
                                ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                                AND ooh.status = 2
                                AND ooh.reference_id NOT IN (
                                    SELECT reference_id
                                    FROM order_payments
                                    WHERE type = 7
                                      AND status = 2
                                )
                            GROUP BY cp.dish_type
                            ORDER BY cp.dish_type DESC
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                }
            }            
            
            $datas=array();
            $taxesarr=array();
            $salesarr=array();
            $ncsalesarr=array();
            $dishsalesarr=array();
            $onlinepaymentsarr=array();

            $datas[]=array(
                'cashier'=>$cashiername,
                'total_collection'=>round($payments[0][0]['total_amount']-$payments[0][0]['no_charge_with_tax'],2),
                'cash'=>round($payments[0][0]['cash'],2),
                'card'=>round($payments[0][0]['card'],2),
                'online'=>round($payments[0][0]['online'],2),
                'upi'=>round($payments[0][0]['upi'],2),
                'hold'=>round($payments[0][0]['hold'],2),
                'storecard'=>round($payments[0][0]['storecard'],2),
                'no_charge'=>round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'],2),
                'no_charge_with_tax'=>round($payments[0][0]['no_charge_with_tax'],2),
                'subtotal'=>round($transactionsubtotal[0][0]['price'],2),
                'discount'=>round($transactionsubtotal[0][0]['discount'],2),
                'taxable_amount'=>round($taxable[0][0]['total_taxable'],2),
                'nontaxable_amount'=>round($nontaxable[0][0]['total_nontaxable'],2),
                'nctaxable_amount'=>round($nctaxable[0][0]['total_taxable'],2),
                'ncnontaxable_amount'=>round($ncnontaxable[0][0]['total_nontaxable'],2),
                'service_charge'=>round($transactions[0][0]['servicecharge'],2),
                'delivery_charge'=>round($transactions[0][0]['delivery_charge'],2),
                'packing_charge'=>round($transactions[0][0]['packing_charge'],2),
                'net_sale'=>round($net_amount_query[0][0]['net_amount'],2),
                'ncnet_sale'=>round($ncnet_amount_query[0][0]['net_amount'],2),
                'total_tax'=>round($transactions[0][0]['total_tax'],2),
                'nctotal_tax'=>round($transactionsnc[0][0]['total_tax'],2),
                'bill_count'=>round($transactions[0][0]['total_count'],2),
                'net_amount'=>round($transactions[0][0]['amount'],2),
                'round'=>round($transactions[0][0]['round'],2),
                'pax'=>round($transactions[0][0]['pax'],2)
            );
        
            foreach($onlinepayments as $onlinepayment){
                $onlinepaymentsarr[]=array(
                    'type'=>$onlinepayment['order_payments']['type_value'],
                    'amount'=>$onlinepayment[0]['total_amount']
                );
            }
            
            foreach($taxes as $tax){
                $taxesarr[]=array(
                    'tax_name'=>$tax['order_tax']['tax_name'].'('.$tax['order_tax']['tax_percentage'].'%)',
                    'tax_value'=>$tax[0]['tax_value']
                );
            }
            
            foreach($sales as $sale){
                // print_r($sale);exit;
                $salesarr[]=array(
                    'kds'=>$sale['final']['kds_name'],
                    'kds_value'=>round($sale['final']['value'],2),
                    'tax_percentage'=>$sale['final']['tax_percentage'],
                );
            }
            
            foreach($ncsales as $ncsale){
                // print_r($sale);exit;
                $ncsalesarr[]=array(
                    'kds'=>$ncsale['final']['kds_name'],
                    'kds_value'=>round($ncsale['final']['value'],2),
                    'tax_percentage'=>$ncsale['final']['tax_percentage'],
                );
            }
            
            foreach($dish_sales as $dish_sale){
                // print_r($sale);exit;
                $dishsalesarr[]=array(
                    'dish_type'=>$dish_sale['cp']['dish_type'],
                    'total_amount'=>round($dish_sale['0']['total_amount'],2)
                );
            }
            
            $this->set(compact('startdate','enddate','datas','taxesarr','salesarr','ncsalesarr','dishsalesarr','onlinepaymentsarr'));
        }
    }
    */

    /*
    public function dsr_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('0 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        if (!empty($this->request->data['Search']['cashier'])) {
            $loc_id = $this->request->data['Search']['cashier'];
        } else {
            $loc_id = 0; 
        }
        
        if($loc_id){
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$loc_id)));

            $cashiername=$cashiernames['Location']['name'];

            $where_location="";
            $where_location = " and store_id = " . (int)$loc_id;
            
            $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT sum(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id and store_id=order_payments.store_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT 
                    type_value,
                    SUM(amount) AS total_amount
                FROM order_payments
                WHERE 
                    type = 11 and
                     status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                GROUP BY type_value
            ");
            
            $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
            $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id ");
            
            $net_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
                        $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
            ");
            $sc_base_sales = $this->Order_orderhistory->query("
                SELECT cp.dish_type,
                    ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                    AND ooh.status = 2 $where_location
                    AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                GROUP BY cp.dish_type
            ");

            
            $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
        }else{
            $cashiername='All Stores';
            if($userRole!='admin'){
                
                $where_location = "AND store_id IN (" . $userLocationId . ")";
            
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location ) $where_location GROUP by tax_id ");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");
                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                    GROUP BY cp.dish_type
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            }else{
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE  status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' ");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)) and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");

                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");
                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2)
                    GROUP BY cp.dish_type
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            }
        }
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
    
        $users=$this->Location->find('all',array('conditions'=>$conditions));
        
        $this->set(compact('users'));
        
        // Last sync time for DSR
        $lastSyncData = $this->_getLastSyncTimes();
        $lastPushTime = $lastSyncData['push']['time'] ?? 'Never';
        $lastPullTime = $lastSyncData['pull']['time'] ?? 'Never';
        $lastPushBills = $lastSyncData['push']['bills_synced'] ?? 0;
        $lastPushFailed = $lastSyncData['push']['bills_failed'] ?? 0;

        $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','sc_base_sales','net_amount_query','taxable','nontaxable','lastPushTime','lastPullTime','lastPushBills','lastPushFailed'));
       // $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','net_amount_query','taxable','nontaxable'));
    }

    public function dsr_reportexport() { 
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $cashier_id = $_GET['cashier'];
        $cashiername = 'All Stores';
    
        if ($cashier_id) {
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
            $cashiername=$cashiernames['Location']['name'];
        }
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $datas = array();
        
        $allTaxTypes = [];
        $allSalesTypes = [];
        $allonlinepayTypes = [];   // ⭐ ADD
        $alldishTypes = [];
        $ncallSalesTypes = [];

        $period = new DatePeriod(
            new DateTime($startdate),
            new DateInterval('P1D'),
            (new DateTime($enddate))->modify('+1 day')
        );
    
        foreach ($period as $dateObj) {
            $day = $dateObj->format('Y-m-d');
            
            $dayStart = $day . ' ' . shiftstart;
            $dayEnd   = date('Y-m-d', strtotime($day . ' +1 day')) . ' ' . shiftend;

            if($userRole!='admin' ){
                $cashierFilter = $cashier_id ? " and store_id=$cashier_id" : " AND store_id IN (" . $userLocationId . ")";
            }else{
                $cashierFilter = $cashier_id ? " and store_id=$cashier_id" : '';
            }
            
            $noChargeFilter = "reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)";
    
            $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,
                SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,
                SUM(IF(type=2,amount,0)) AS card,
                SUM(IF(type=6,amount,0)) AS upi,
                SUM(IF(type=9,amount,0)) AS online,
                SUM(IF(type=7,amount,0)) AS no_charge_with_tax,
                SUM(IF(type=7,round(amount-(SELECT total_tax from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $cashierFilter limit 1),2),0)) AS no_charge,
                SUM(IF(type=8,amount,0)) AS storecard
                FROM order_payments
                WHERE status=2 and created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT type_value, SUM(amount) AS total_amount
                FROM order_payments
                WHERE type = 11
                  AND status = 2
                  AND created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                GROUP BY type_value
            ");
            
            foreach ($onlinepayments as $op) {
                $key = $op['order_payments']['type_value'];
                $allonlinepayTypes[$key] = true;
            }

            $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,
                SUM(total_tax) AS total_tax,
                SUM(servicecharge) AS servicecharge,
                SUM(discount) AS discount,
                SUM(delivery_charge) AS delivery_charge,
                SUM(packing_charge) AS packing_charge,
                SUM(amount) AS amount,
                SUM(price) AS price,
                SUM(round) AS roundamount
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter AND $noChargeFilter");
     
            $transactionsnc = $this->Order_transaction->query("SELECT
                SUM(total_tax) AS total_tax
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter AND reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)");
     
            $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,
                SUM(discount) AS discount FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter");
    
            $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$dayStart' and '$dayEnd' and status=2 $cashierFilter and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)  GROUP by tax_id");
            foreach ($taxes as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $allTaxTypes[$key] = true;
            }
    
            $net_amount_query = $this->Order_transaction->query("
                SELECT 
                    SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                    AND ot.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT 
                    SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                    AND ot.reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )
            ");


        // Define mapping
            $dishTypeMap = [
                0 => 'Food',
                1 => 'Beverage',
                2 => 'Liquor',
                3 => 'Others'
            ];
            // $dish_sales = $this->Order_orderhistory->query("
            //     SELECT 
            //         cp.dish_type,
            //         SUM(ooh.quantity)                         AS total_qty,
            //         ROUND(SUM(ooh.price * ooh.quantity), 2)   AS total_amount
            //     FROM order_orderhistories ooh
            //     INNER JOIN catalog_product cp 
            //         ON cp.id = ooh.product_id
            //     WHERE 
            //         ooh.created BETWEEN '$dayStart' AND '$dayEnd'
            //         AND ooh.status = 2 $cashierFilter
            //         AND ooh.reference_id NOT IN (
            //             SELECT reference_id 
            //             FROM order_payments 
            //             WHERE type = 7 
            //               AND status = 2 $cashierFilter
            //         )
            //     GROUP BY cp.dish_type
            //     ORDER BY cp.dish_type DESC
            // ");
                        $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$dayStart' AND '$dayEnd'
                        AND ooh.status = 2 $cashierFilter
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $cashierFilter
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
            ");
            $sc_base_sales = $this->Order_orderhistory->query("
                SELECT cp.dish_type,
                    ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                WHERE ooh.created BETWEEN '$dayStart' AND '$dayEnd'
                    AND ooh.status = 2 $cashierFilter
                    AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
                GROUP BY cp.dish_type
            ");
            
            // Collect all types
            foreach ($dish_sales as $ds) {
                $type = $ds['cp']['dish_type'];
                $alldishSalesTypes[$type] = true;
            }
            
            
            $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage != 0 $cashierFilter AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
                    
            $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage = 0 $cashierFilter AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
            
            $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage != 0 $cashierFilter AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
                    
            $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage = 0 $cashierFilter AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
            
            $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$dayStart' and '$dayEnd' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter) $cashierFilter) $cashierFilter GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            foreach ($sales as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $allSalesTypes[$key] = true;
            }
            
            $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$dayStart' and '$dayEnd' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter) $cashierFilter) $cashierFilter GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            foreach ($ncsales as $s) {
                $key = 'NC - '. $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncallSalesTypes[$key] = true;
            }
            
            $datas[] = array(
                'date' => $day,
                'cashier' => $cashiername,
                'total_collection' => round($payments[0][0]['total_amount'] - $payments[0][0]['no_charge_with_tax'], 2),
                'cash' => round($payments[0][0]['cash'], 2),
                'card' => round($payments[0][0]['card'], 2),
                'online' => round($payments[0][0]['online'], 2),
                'online_payments' => $onlinepayments,
                'upi' => round($payments[0][0]['upi'], 2),
                'hold' => round($payments[0][0]['hold'], 2),
                'storecard' => round($payments[0][0]['storecard'], 2),
                'no_charge' => round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'], 2),
                'no_charge_with_tax' => round($payments[0][0]['no_charge_with_tax'], 2),
                'subtotal' => round($transactionsubtotal[0][0]['price'], 2),
                'discount' => round($transactionsubtotal[0][0]['discount'], 2),
                'taxable_amount' => round($taxable[0][0]['total_taxable']-$transactionsubtotal[0][0]['discount'], 2),
                'nontaxable_amount' => round($nontaxable[0][0]['total_nontaxable'], 2),
                'nctaxable_amount' => round($nctaxable[0][0]['total_taxable'], 2),
                'ncnontaxable_amount' => round($ncnontaxable[0][0]['total_nontaxable'], 2),
                'service_charge' => round($transactions[0][0]['servicecharge'], 2),
                'delivery_charge' => round($transactions[0][0]['delivery_charge'], 2),
                'packing_charge' => round($transactions[0][0]['packing_charge'], 2),
                'total_tax' => round($transactions[0][0]['total_tax'], 2),
                'nctotal_tax' => round($transactionsnc[0][0]['total_tax'], 2),
                'bill_count' => round($transactions[0][0]['total_count'], 2),
                'net_amount' => round($transactions[0][0]['amount'], 2),
                'round' => $transactions[0][0]['roundamount'],
                'taxes' => $taxes,
                'sales' => $sales,
                'ncsales' => $ncsales,
                'dish_sales' => $dish_sales,
                'net_sale' =>$net_amount_query[0][0]['net_amount'],
                'ncnet_sale' =>$ncnet_amount_query[0][0]['net_amount'],
                'pax' => $transactions[0][0]['pax'],
                'sc_base_sales' => $sc_base_sales
            );
        }
            
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("DSR Report Export");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('DSR Report');
        
        $taxColumns = array_keys($allTaxTypes);
        $salesColumns = array_keys($allSalesTypes);
        $ncsalesColumns = array_keys($ncallSalesTypes);
        
        sort($taxColumns);
        sort($salesColumns);
        sort($ncsalesColumns);
        
        // Use mapped names as columns
        $dishsalesColumns = [];
        foreach (array_keys($alldishSalesTypes) as $type) {
            $dishsalesColumns[] = $dishTypeMap[$type] ?? $type;
        }
        sort($dishsalesColumns);
        
        $online_payments = array_keys($allonlinepayTypes);
        sort($online_payments);
        
        $baseHeaders = [
            'Date','Store','Total Collection','Cash','Card','Upi','Online',
        ];
        
        $afterOnlineHeaders = [
            'Storecard','Hold Bill','No Charge','No Charge With Tax',
            'Subtotal','Discount','Taxable','Non Taxable','NC Taxable','NC Non Taxable',
            'NC Net Sale','NC Total Tax','No Charge','No Charge With Tax',
            'Service','Delivery','Packing','Net Sale','Total Tax','Net Amount',
            'Round','Bill Count','PAX'
        ];
        
        $headers = array_merge(
            $baseHeaders,
            $online_payments,   // ⭐ dynamic inserted here
            $afterOnlineHeaders,
            $taxColumns,
            $salesColumns,
            $ncsalesColumns,
            $dishsalesColumns,
            ['SC Total','SC on GST Items (5%)','SC on VAT Items (18.9%)','SGST on SC (2.5%)','CGST on SC (2.5%)','VAT on SC (18.9%)']
        );
        
        $sheet->fromArray($headers, null, 'A1');

        // $headers = ['Date', 'Store', 'Total Collection', 'Cash', 'Card', 'Online', 'Upi', 'Storecard', 'Hold Bill', 'No Charge', 'No Charge With Tax', 'Subtotal', 'Discount', 'Taxable', 'Non Taxable', 'NC Taxable', 'NC Non Taxable', 'NC Net Sale', 'NC Total Tax', 'No Charge', 'No Charge With Tax', 'Service', 'Delivery', 'Packing', 'Net Sale', 'Total Tax', 'Net Amount', 'Round', 'Bill Count', 'PAX'];
        // $headers = array_merge($headers, $taxColumns, $salesColumns,$ncsalesColumns,$dishsalesColumns);
        // $sheet->fromArray($headers, null, 'A1');
        
        $row = 2;
        foreach ($datas as $data) {
            $colIndex = 0; // ✅ RESET EVERY ROW

            // print_r($data['round']);exit;
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['date']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['cashier']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['total_collection']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['cash']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['card']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['upi']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['online']);
            
            $onlinepaymentValues = array_fill_keys($online_payments, 0);
            foreach ($data['online_payments'] as $t) {
                $key = $t['order_payments']['type_value'];
                $onlinepaymentValues[$key] = round($t[0]['total_amount'], 2);
            }
            
            foreach ($online_payments as $op) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $onlinepaymentValues[$op]);
            }
            
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['storecard']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['hold']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge_with_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['subtotal']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['discount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['taxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nctaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['ncnontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['ncnet_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nctotal_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge_with_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['service_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['delivery_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['packing_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['net_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['total_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['net_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['round']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['bill_count']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['pax']);
            
            $taxValues = array_fill_keys($taxColumns, 0);
            foreach ($data['taxes'] as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $taxValues[$key] = round($t['0']['tax_value'], 2);
            }
            
            foreach ($taxColumns as $taxCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $taxValues[$taxCol]);
            }
    
            $salesValues = array_fill_keys($salesColumns, 0);
            foreach ($data['sales'] as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $salesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($salesColumns as $salesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $salesValues[$salesCol]);
            }
            
            $ncsalesValues = array_fill_keys($ncsalesColumns, 0);
            foreach ($data['ncsales'] as $s) {
                $key = 'NC - '. $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncsalesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($ncsalesColumns as $ncsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $ncsalesValues[$ncsalesCol]);
            }
            
            $dishsalesValues = array_fill_keys($dishsalesColumns, 0);
            
            foreach ($data['dish_sales'] as $ds) {
            
                if (!isset($ds['cp']['dish_type'])) {
                    continue;
                }
            
                $type = (int)$ds['cp']['dish_type'];
                $key  = $dishTypeMap[$type] ?? $type;
            
                if (array_key_exists($key, $dishsalesValues)) {
                    $dishsalesValues[$key] = round((float)$ds[0]['total_amount'], 2);
                }
            }

            
            // Write to Excel
            foreach ($dishsalesColumns as $dishsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $dishsalesValues[$dishsalesCol]);
            }

            // SC breakup columns
            $sc_sagg5 = 0; $sc_sagg189 = 0;
            foreach ($data['sales'] as $s) {
                if ($s['final']['tax_percentage'] == 5) $sc_sagg5 += $s['final']['value'];
                elseif ($s['final']['tax_percentage'] == 18.9) $sc_sagg189 += $s['final']['value'];
            }
            $sc_bfv = 0; $sc_blq = 0;
            foreach ($data['sc_base_sales'] as $b) {
                $dt = (int)$b['cp']['dish_type'];
                if ($dt == 0 || $dt == 1) $sc_bfv += $b[0]['base_amount'];
                elseif ($dt == 2) $sc_blq += $b[0]['base_amount'];
            }
            $sc_gv = round($sc_sagg5 - $sc_bfv, 2);
            $sc_vv = round($sc_sagg189 - $sc_blq, 2);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv + $sc_vv, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $sc_gv);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $sc_vv);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv * 0.025, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv * 0.025, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_vv * 0.189, 2));

            $row++;
        }
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="DSR_REPORT.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    public function dsr_reportpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range= $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $cashier_id=$this->request->data['cashier'];
            if($cashier_id){
                $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
                $cashiername=$cashiernames['Location']['name'];

                $where_location=" and store_id=$cashier_id";
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
            
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
    
                                $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                ");
                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                    GROUP BY cp.dish_type
                ");
                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
            }else{
                $cashiername='All Stores';
                if($userRole!='admin' ){
                    $where_location=" AND store_id IN (" . $userLocationId . ")";
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                    
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
    
                                        $dish_sales = $this->Order_orderhistory->query("
                            SELECT
                                cp.dish_type,
                                SUM(ooh.quantity) AS total_qty,
                                ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                            FROM order_orderhistories ooh
                            INNER JOIN catalog_product cp
                                ON cp.id = ooh.product_id
                            INNER JOIN (
                                SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                                FROM order_tax
                                WHERE status != 0
                                GROUP BY orderhistory_id
                            ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                            WHERE
                                ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                                AND ooh.status = 2 $where_location
                                AND ooh.reference_id NOT IN (
                                    SELECT reference_id
                                    FROM order_payments
                                    WHERE type = 7
                                      AND status = 2 $where_location
                                )
                            GROUP BY cp.dish_type
                            ORDER BY cp.dish_type DESC
                    ");
                    $sc_base_sales = $this->Order_orderhistory->query("
                        SELECT cp.dish_type,
                            ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                        LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                        WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                        GROUP BY cp.dish_type
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                }else{
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' ");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
    
                                        $dish_sales = $this->Order_orderhistory->query("
                            SELECT
                                cp.dish_type,
                                SUM(ooh.quantity) AS total_qty,
                                ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                            FROM order_orderhistories ooh
                            INNER JOIN catalog_product cp
                                ON cp.id = ooh.product_id
                            INNER JOIN (
                                SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                                FROM order_tax
                                WHERE status != 0
                                GROUP BY orderhistory_id
                            ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                            WHERE
                                ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                                AND ooh.status = 2
                                AND ooh.reference_id NOT IN (
                                    SELECT reference_id
                                    FROM order_payments
                                    WHERE type = 7
                                      AND status = 2
                                )
                            GROUP BY cp.dish_type
                            ORDER BY cp.dish_type DESC
                    ");
                    $sc_base_sales = $this->Order_orderhistory->query("
                        SELECT cp.dish_type,
                            ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                        LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                        WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2)
                        GROUP BY cp.dish_type
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                }
            }            
            
            $datas=array();
            $taxesarr=array();
            $salesarr=array();
            $ncsalesarr=array();
            $dishsalesarr=array();
            $onlinepaymentsarr=array();

            $datas[]=array(
                'cashier'=>$cashiername,
                'total_collection'=>round($payments[0][0]['total_amount']-$payments[0][0]['no_charge_with_tax'],2),
                'cash'=>round($payments[0][0]['cash'],2),
                'card'=>round($payments[0][0]['card'],2),
                'online'=>round($payments[0][0]['online'],2),
                'upi'=>round($payments[0][0]['upi'],2),
                'hold'=>round($payments[0][0]['hold'],2),
                'storecard'=>round($payments[0][0]['storecard'],2),
                'no_charge'=>round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'],2),
                'no_charge_with_tax'=>round($payments[0][0]['no_charge_with_tax'],2),
                'subtotal'=>round($transactionsubtotal[0][0]['price'],2),
                'discount'=>round($transactionsubtotal[0][0]['discount'],2),
                'taxable_amount'=>round($taxable[0][0]['total_taxable'],2),
                'nontaxable_amount'=>round($nontaxable[0][0]['total_nontaxable'],2),
                'nctaxable_amount'=>round($nctaxable[0][0]['total_taxable'],2),
                'ncnontaxable_amount'=>round($ncnontaxable[0][0]['total_nontaxable'],2),
                'service_charge'=>round($transactions[0][0]['servicecharge'],2),
                'delivery_charge'=>round($transactions[0][0]['delivery_charge'],2),
                'packing_charge'=>round($transactions[0][0]['packing_charge'],2),
                'net_sale'=>round($net_amount_query[0][0]['net_amount'],2),
                'ncnet_sale'=>round($ncnet_amount_query[0][0]['net_amount'],2),
                'total_tax'=>round($transactions[0][0]['total_tax'],2),
                'nctotal_tax'=>round($transactionsnc[0][0]['total_tax'],2),
                'bill_count'=>round($transactions[0][0]['total_count'],2),
                'net_amount'=>round($transactions[0][0]['amount'],2),
                'round'=>round($transactions[0][0]['round'],2),
                'pax'=>round($transactions[0][0]['pax'],2)
            );
        
            foreach($onlinepayments as $onlinepayment){
                $onlinepaymentsarr[]=array(
                    'type'=>$onlinepayment['order_payments']['type_value'],
                    'amount'=>$onlinepayment[0]['total_amount']
                );
            }
            
            foreach($taxes as $tax){
                $taxesarr[]=array(
                    'tax_name'=>$tax['order_tax']['tax_name'].'('.$tax['order_tax']['tax_percentage'].'%)',
                    'tax_value'=>$tax[0]['tax_value']
                );
            }
            
            foreach($sales as $sale){
                // print_r($sale);exit;
                $salesarr[]=array(
                    'kds'=>$sale['final']['kds_name'],
                    'kds_value'=>round($sale['final']['value'],2),
                    'tax_percentage'=>$sale['final']['tax_percentage'],
                );
            }
            
            foreach($ncsales as $ncsale){
                // print_r($sale);exit;
                $ncsalesarr[]=array(
                    'kds'=>$ncsale['final']['kds_name'],
                    'kds_value'=>round($ncsale['final']['value'],2),
                    'tax_percentage'=>$ncsale['final']['tax_percentage'],
                );
            }
            
            foreach($dish_sales as $dish_sale){
                // print_r($sale);exit;
                $dishsalesarr[]=array(
                    'dish_type'=>$dish_sale['cp']['dish_type'],
                    'total_amount'=>round($dish_sale['0']['total_amount'],2)
                );
            }

            // SC breakup for PDF
            $pdf_sagg5 = 0; $pdf_sagg189 = 0;
            foreach($salesarr as $s) {
                if ($s['tax_percentage'] == 5) $pdf_sagg5 += $s['kds_value'];
                elseif ($s['tax_percentage'] == 18.9) $pdf_sagg189 += $s['kds_value'];
            }
            $pdf_bfv = 0; $pdf_blq = 0;
            foreach($sc_base_sales as $b) {
                $dt = (int)$b['cp']['dish_type'];
                if ($dt == 0 || $dt == 1) $pdf_bfv += $b[0]['base_amount'];
                elseif ($dt == 2) $pdf_blq += $b[0]['base_amount'];
            }
            $pdf_sc_gst = round($pdf_sagg5 - $pdf_bfv, 2);
            $pdf_sc_vat = round($pdf_sagg189 - $pdf_blq, 2);
            $scbreakuparr = array(
                'sc_total'   => round($pdf_sc_gst + $pdf_sc_vat, 2),
                'sc_gst'     => $pdf_sc_gst,
                'sc_vat'     => $pdf_sc_vat,
                'sgst_on_sc' => round($pdf_sc_gst * 0.025, 2),
                'cgst_on_sc' => round($pdf_sc_gst * 0.025, 2),
                'vat_on_sc'  => round($pdf_sc_vat * 0.189, 2),
            );
            
            $this->set(compact('startdate','enddate','datas','taxesarr','salesarr','ncsalesarr','dishsalesarr','scbreakuparr','onlinepaymentsarr'));
        }
    }
    */

    public function dsr_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('0 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        if (!empty($this->request->data['Search']['cashier'])) {
            $loc_id = $this->request->data['Search']['cashier'];
        } else {
            $loc_id = 0; 
        }
        
        if($loc_id){
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$loc_id)));

            $cashiername=$cashiernames['Location']['name'];

            $where_location="";
            $where_location = " and store_id = " . (int)$loc_id;
            
            $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT sum(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id and store_id=order_payments.store_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT 
                    type_value,
                    SUM(amount) AS total_amount
                FROM order_payments
                WHERE 
                    type = 11 and
                     status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                GROUP BY type_value
            ");
            
            $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round,SUM(other_taxes) AS other_taxes FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
            $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
            $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id ");
            
            $net_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT 
                    round(SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    AND ot.reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
            ");
            
            $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
            ");

            $dish_saleswithoutservice = $this->Order_orderhistory->query("
                SELECT 
                    cp.dish_type,
                    SUM(ooh.quantity) AS total_qty,
                    ROUND(
                        SUM(
                            (ooh.price * ooh.quantity) 
                            * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                        ), 
                    2) AS total_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp 
                    ON cp.id = ooh.product_id
                LEFT JOIN (
                    SELECT 
                        orderhistory_id,
                        MAX(discount_percentage) AS discount_percentage
                    FROM order_tax
                    WHERE status != 0
                    GROUP BY orderhistory_id
                ) ot ON ot.orderhistory_id = ooh.id
                WHERE 
                    ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                    AND ooh.status = 2 $where_location
                    AND ooh.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )
                GROUP BY cp.dish_type
                ORDER BY cp.dish_type DESC
            ");
            $sc_base_sales = $this->Order_orderhistory->query("
                SELECT cp.dish_type,
                    ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                    AND ooh.status = 2 $where_location
                    AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                GROUP BY cp.dish_type
            ");

            
            $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
                    
            $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $where_location
                    )");
            
            $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
        }else{
            $cashiername='All Stores';
            if($userRole!='admin'){
                
                $where_location = "AND store_id IN (" . $userLocationId . ")";
            
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round,SUM(other_taxes) AS other_taxes FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 $where_location");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location ) $where_location GROUP by tax_id ");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $dish_saleswithoutservice = $this->Order_orderhistory->query("
                    SELECT 
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(
                            SUM(
                                (ooh.price * ooh.quantity)
                                * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                            ),
                        2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp 
                        ON cp.id = ooh.product_id
                    LEFT JOIN (
                        SELECT 
                            orderhistory_id,
                            MAX(discount_percentage) AS discount_percentage
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot ON ot.orderhistory_id = ooh.id
                    WHERE 
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                    GROUP BY cp.dish_type
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            
            }else{
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE  status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' and '$endDatetime' ");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) as pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price,SUM(other_taxes) AS other_taxes  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' and '$endDatetime' and status=2");
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)) and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                ");

                $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $dish_saleswithoutservice = $this->Order_orderhistory->query("
                    SELECT 
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(
                            SUM(
                                (ooh.price * ooh.quantity)
                                * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                            ),
                        2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp 
                        ON cp.id = ooh.product_id
                    LEFT JOIN (
                        SELECT 
                            orderhistory_id,
                            MAX(discount_percentage) AS discount_percentage
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot ON ot.orderhistory_id = ooh.id
                    WHERE 
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2)
                    GROUP BY cp.dish_type
                ");

                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            }
        }
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
    
        $users=$this->Location->find('all',array('conditions'=>$conditions));
        
        $this->set(compact('users'));
        
        // Last sync time for DSR
        $lastSyncData = $this->_getLastSyncTimes();
        $lastPushTime = $lastSyncData['push']['time'] ?? 'Never';
        $lastPullTime = $lastSyncData['pull']['time'] ?? 'Never';
        $lastPushBills = $lastSyncData['push']['bills_synced'] ?? 0;
        $lastPushFailed = $lastSyncData['push']['bills_failed'] ?? 0;
		$other_taxes_sum = round($transactions[0][0]['other_taxes'], 2);

        $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','sc_base_sales','net_amount_query','taxable','nontaxable','lastPushTime','lastPullTime','lastPushBills','lastPushFailed','dish_saleswithoutservice','other_taxes_sum'));
       // $this->set(compact('onlinepayments','ncnet_amount_query','nctaxable','ncnontaxable','ncsales','payments','cashiername','transactions','taxes','taxable_price','sales','transactionsubtotal','transactionsnc','dish_sales','net_amount_query','taxable','nontaxable'));
    }

    public function dsr_reportexport() { 
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $cashier_id = $_GET['cashier'];
        $cashiername = 'All Stores';
    
        if ($cashier_id) {
            $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
            $cashiername=$cashiernames['Location']['name'];
        }
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $datas = array();
        
        $allTaxTypes = [];
        $allSalesTypes = [];
        $allonlinepayTypes = [];   // ⭐ ADD
        $alldishTypes = [];
        $ncallSalesTypes = [];
        $alldishSalesWithoutTypes = [];

        $period = new DatePeriod(
            new DateTime($startdate),
            new DateInterval('P1D'),
            (new DateTime($enddate))->modify('+1 day')
        );
    
        foreach ($period as $dateObj) {
            $day = $dateObj->format('Y-m-d');
            
            $dayStart = $day . ' ' . shiftstart;
            $dayEnd   = date('Y-m-d', strtotime($day . ' +1 day')) . ' ' . shiftend;

            if($userRole!='admin' ){
                $cashierFilter = $cashier_id ? " and store_id=$cashier_id" : " AND store_id IN (" . $userLocationId . ")";
            }else{
                $cashierFilter = $cashier_id ? " and store_id=$cashier_id" : '';
            }
            
            $noChargeFilter = "reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)";
    
            $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,
                SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,
                SUM(IF(type=2,amount,0)) AS card,
                SUM(IF(type=6,amount,0)) AS upi,
                SUM(IF(type=9,amount,0)) AS online,
                SUM(IF(type=7,amount,0)) AS no_charge_with_tax,
                SUM(IF(type=7,round(amount-(SELECT total_tax from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $cashierFilter limit 1),2),0)) AS no_charge,
                SUM(IF(type=8,amount,0)) AS storecard
                FROM order_payments
                WHERE status=2 and created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter");
            
            $onlinepayments = $this->Order_payment->query("
                SELECT type_value, SUM(amount) AS total_amount
                FROM order_payments
                WHERE type = 11
                  AND status = 2
                  AND created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                GROUP BY type_value
            ");
            
            foreach ($onlinepayments as $op) {
                $key = $op['order_payments']['type_value'];
                $allonlinepayTypes[$key] = true;
            }

            $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,
                SUM(total_tax) AS total_tax,
                SUM(servicecharge) AS servicecharge,
                SUM(discount) AS discount,
                SUM(delivery_charge) AS delivery_charge,
                SUM(packing_charge) AS packing_charge,
                SUM(amount) AS amount,
                SUM(price) AS price,
                SUM(round) AS roundamount,
				SUM(other_taxes) AS other_taxes
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter AND $noChargeFilter");
     
            $transactionsnc = $this->Order_transaction->query("SELECT
                SUM(total_tax) AS total_tax
                FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter AND reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)");
     
            $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,
                SUM(discount) AS discount FROM order_transactions
                WHERE created BETWEEN '$dayStart' AND '$dayEnd' AND status=2 $cashierFilter");
    
            $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$dayStart' and '$dayEnd' and status=2 $cashierFilter and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter)  GROUP by tax_id");
            foreach ($taxes as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $allTaxTypes[$key] = true;
            }
    
            $net_amount_query = $this->Order_transaction->query("
                SELECT 
                    SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                    AND ot.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )
            ");
            
            $ncnet_amount_query = $this->Order_transaction->query("
                SELECT 
                    SUM(ot.price)
                    - IFNULL(SUM(ot.discount), 0) AS net_amount
                FROM order_transactions ot
                WHERE 
                    ot.status = 2
                    AND ot.created BETWEEN '$dayStart' AND '$dayEnd' $cashierFilter
                    AND ot.reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )
            ");


        // Define mapping
            $dishTypeMap = [
                0 => 'Food',
                1 => 'Beverage',
                2 => 'Liquor',
                3 => 'Others'
            ];
            $dish_sales = $this->Order_orderhistory->query("
                SELECT
                    cp.dish_type,
                    SUM(ooh.quantity) AS total_qty,
                    ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp
                    ON cp.id = ooh.product_id
                INNER JOIN (
                    SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                    FROM order_tax
                    WHERE status != 0
                    GROUP BY orderhistory_id
                ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                WHERE
                    ooh.created BETWEEN '$dayStart' AND '$dayEnd'
                    AND ooh.status = 2 $cashierFilter
                    AND ooh.reference_id NOT IN (
                        SELECT reference_id
                        FROM order_payments
                        WHERE type = 7
                          AND status = 2 $cashierFilter
                    )
                GROUP BY cp.dish_type
                ORDER BY cp.dish_type DESC
            ");
            $sc_base_sales = $this->Order_orderhistory->query("
                SELECT cp.dish_type,
                    ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                WHERE ooh.created BETWEEN '$dayStart' AND '$dayEnd'
                    AND ooh.status = 2 $cashierFilter
                    AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $cashierFilter)
                GROUP BY cp.dish_type
            ");
            
            // Collect all types
            foreach ($dish_sales as $ds) {
                $type = $ds['cp']['dish_type'];
                $alldishSalesTypes[$type] = true;
            }
            
            $dish_saleswithoutservice = $this->Order_orderhistory->query("
                SELECT 
                    cp.dish_type,
                    SUM(ooh.quantity) AS total_qty,
                    ROUND(
                        SUM(
                            (ooh.price * ooh.quantity) 
                            * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                        ), 
                    2) AS total_amount
                FROM order_orderhistories ooh
                INNER JOIN catalog_product cp 
                    ON cp.id = ooh.product_id
                LEFT JOIN (
                    SELECT 
                        orderhistory_id,
                        MAX(discount_percentage) AS discount_percentage
                    FROM order_tax
                    WHERE status != 0
                    GROUP BY orderhistory_id
                ) ot ON ot.orderhistory_id = ooh.id
                WHERE 
                    ooh.created BETWEEN '$dayStart' AND '$dayEnd'
                    AND ooh.status = 2 $cashierFilter
                    AND ooh.reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )
                GROUP BY cp.dish_type
                ORDER BY cp.dish_type DESC
            ");
            
            foreach ($dish_saleswithoutservice as $dsw) {
                $type = $dsw['cp']['dish_type'];
                $alldishSalesWithoutTypes[$type] = true;
            }
            
            $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage != 0 $cashierFilter AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
                    
            $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage = 0 $cashierFilter AND
                    reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
            
            $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage != 0 $cashierFilter AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
                    
            $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$dayStart' AND '$dayEnd' and total_tax_percentage = 0 $cashierFilter AND
                    reference_id IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 
                          AND status = 2 $cashierFilter
                    )");
            
            $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$dayStart' and '$dayEnd' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter) $cashierFilter) $cashierFilter GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            foreach ($sales as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $allSalesTypes[$key] = true;
            }
            
            $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$dayStart' and '$dayEnd' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $cashierFilter) $cashierFilter) $cashierFilter GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
            foreach ($ncsales as $s) {
                $key = 'NC - '. $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncallSalesTypes[$key] = true;
            }
            
            $datas[] = array(
                'date' => $day,
                'cashier' => $cashiername,
                'total_collection' => round($payments[0][0]['total_amount'] - $payments[0][0]['no_charge_with_tax'], 2),
                'cash' => round($payments[0][0]['cash'], 2),
                'card' => round($payments[0][0]['card'], 2),
                'online' => round($payments[0][0]['online'], 2),
                'online_payments' => $onlinepayments,
                'upi' => round($payments[0][0]['upi'], 2),
                'hold' => round($payments[0][0]['hold'], 2),
                'storecard' => round($payments[0][0]['storecard'], 2),
                'no_charge' => round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'], 2),
                'no_charge_with_tax' => round($payments[0][0]['no_charge_with_tax'], 2),
                'subtotal' => round($transactionsubtotal[0][0]['price'], 2),
                'discount' => round($transactionsubtotal[0][0]['discount'], 2),
                'taxable_amount' => round($taxable[0][0]['total_taxable']-$transactionsubtotal[0][0]['discount'], 2),
                'nontaxable_amount' => round($nontaxable[0][0]['total_nontaxable'], 2),
                'nctaxable_amount' => round($nctaxable[0][0]['total_taxable'], 2),
                'ncnontaxable_amount' => round($ncnontaxable[0][0]['total_nontaxable'], 2),
                'service_charge' => round($transactions[0][0]['servicecharge'], 2),
                'delivery_charge' => round($transactions[0][0]['delivery_charge'], 2),
                'packing_charge' => round($transactions[0][0]['packing_charge'], 2),
                'total_tax' => round($transactions[0][0]['total_tax'], 2),
                'nctotal_tax' => round($transactionsnc[0][0]['total_tax'], 2),
                'bill_count' => round($transactions[0][0]['total_count'], 2),
                'net_amount' => round($transactions[0][0]['amount'], 2),
                'round' => $transactions[0][0]['roundamount'],
                'taxes' => $taxes,
                'sales' => $sales,
                'ncsales' => $ncsales,
                'dish_saleswithoutservice' => $dish_saleswithoutservice,
                'dish_sales' => $dish_sales,
                'net_sale' =>$net_amount_query[0][0]['net_amount'],
                'ncnet_sale' =>$ncnet_amount_query[0][0]['net_amount'],
                'pax' => $transactions[0][0]['pax'],
                'sc_base_sales' => $sc_base_sales,
				'other_taxes' => round($transactions[0][0]['other_taxes'], 2)
            );
        }
            
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("DSR Report Export");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('DSR Report');
        
        $taxColumns = array_keys($allTaxTypes);
        $salesColumns = array_keys($allSalesTypes);
        $ncsalesColumns = array_keys($ncallSalesTypes);
        
        sort($taxColumns);
        sort($salesColumns);
        sort($ncsalesColumns);
        
        // Use mapped names as columns
        $dishsalesColumns = [];
        foreach (array_keys($alldishSalesTypes) as $type) {
            $dishsalesColumns[] = $dishTypeMap[$type] ?? $type;
        }
        sort($dishsalesColumns);
        
        $dishsalesWithoutColumns = [];

        foreach (array_keys($alldishSalesWithoutTypes) as $type) {
            $dishsalesWithoutColumns[] = 'W/O SC - ' . ($dishTypeMap[$type] ?? $type);
        }
        sort($dishsalesWithoutColumns);

        $online_payments = array_keys($allonlinepayTypes);
        sort($online_payments);
        
        $baseHeaders = [
            'Date','Store','Total Collection','Cash','Card','Upi','Online',
        ];
        
        $afterOnlineHeaders = [
            'Storecard','Hold Bill','No Charge','No Charge With Tax',
            'Subtotal','Discount','Taxable','Non Taxable','NC Taxable','NC Non Taxable',
            'NC Net Sale','NC Total Tax','No Charge','No Charge With Tax',
            'Service','Delivery','Packing','Net Sale','Total Tax','Net Amount',
            'Round','Bill Count','PAX'
        ];
        
        $headers = array_merge(
            $baseHeaders,
            $online_payments,   // ⭐ dynamic inserted here
            $afterOnlineHeaders,
            $taxColumns,
			['Other Charges Tax'], 
            $salesColumns,
            $ncsalesColumns,
            $dishsalesColumns,
            $dishsalesWithoutColumns,
            ['SC Total','SC on GST Items (5%)','SC on VAT Items (18.9%)','SGST on SC (2.5%)','CGST on SC (2.5%)','VAT on SC (18.9%)']
        );
        
        $sheet->fromArray($headers, null, 'A1');

        // $headers = ['Date', 'Store', 'Total Collection', 'Cash', 'Card', 'Online', 'Upi', 'Storecard', 'Hold Bill', 'No Charge', 'No Charge With Tax', 'Subtotal', 'Discount', 'Taxable', 'Non Taxable', 'NC Taxable', 'NC Non Taxable', 'NC Net Sale', 'NC Total Tax', 'No Charge', 'No Charge With Tax', 'Service', 'Delivery', 'Packing', 'Net Sale', 'Total Tax', 'Net Amount', 'Round', 'Bill Count', 'PAX'];
        // $headers = array_merge($headers, $taxColumns, $salesColumns,$ncsalesColumns,$dishsalesColumns);
        // $sheet->fromArray($headers, null, 'A1');
        
        $row = 2;
        foreach ($datas as $data) {
            $colIndex = 0; // ✅ RESET EVERY ROW

            // print_r($data['round']);exit;
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['date']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['cashier']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['total_collection']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['cash']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['card']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['upi']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['online']);
            
            $onlinepaymentValues = array_fill_keys($online_payments, 0);
            foreach ($data['online_payments'] as $t) {
                $key = $t['order_payments']['type_value'];
                $onlinepaymentValues[$key] = round($t[0]['total_amount'], 2);
            }
            
            foreach ($online_payments as $op) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $onlinepaymentValues[$op]);
            }
            
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['storecard']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['hold']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge_with_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['subtotal']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['discount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['taxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nctaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['ncnontaxable_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['ncnet_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['nctotal_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['no_charge_with_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['service_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['delivery_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['packing_charge']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['net_sale']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['total_tax']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['net_amount']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['round']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['bill_count']);
            $sheet->setCellValueByColumnAndRow($colIndex++,$row, $data['pax']);
            
            $taxValues = array_fill_keys($taxColumns, 0);
            foreach ($data['taxes'] as $t) {
                $key = $t['order_tax']['tax_name'] . "(" . $t['order_tax']['tax_percentage'] . "%)";
                $taxValues[$key] = round($t['0']['tax_value'], 2);
            }
			
			if (!empty($data['other_taxes']) && $data['other_taxes'] > 0) {
				$taxValues['Other Charges Taxes'] = $data['other_taxes'];
			}
            
            foreach ($taxColumns as $taxCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $taxValues[$taxCol]);
            }
			
			
			$sheet->setCellValueByColumnAndRow($colIndex++, $row, $taxValues['Other Charges Taxes'] ?? 0);
    
            $salesValues = array_fill_keys($salesColumns, 0);
            foreach ($data['sales'] as $s) {
                $key = $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $salesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($salesColumns as $salesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $salesValues[$salesCol]);
            }
            
            $ncsalesValues = array_fill_keys($ncsalesColumns, 0);
            foreach ($data['ncsales'] as $s) {
                $key = 'NC - '. $s['final']['kds_name'] . "(" . $s['final']['tax_percentage'] . "%)";
                $ncsalesValues[$key] = round($s['final']['value'], 2);
            }
            foreach ($ncsalesColumns as $ncsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $ncsalesValues[$ncsalesCol]);
            }
            
            $dishsalesValues = array_fill_keys($dishsalesColumns, 0);
            
            foreach ($data['dish_sales'] as $ds) {
            
                if (!isset($ds['cp']['dish_type'])) {
                    continue;
                }
            
                $type = (int)$ds['cp']['dish_type'];
                $key  = $dishTypeMap[$type] ?? $type;
            
                if (array_key_exists($key, $dishsalesValues)) {
                    $dishsalesValues[$key] = round((float)$ds[0]['total_amount'], 2);
                }
            }

            
            // Write to Excel
            foreach ($dishsalesColumns as $dishsalesCol) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $dishsalesValues[$dishsalesCol]);
            }

            $dishsalesWithoutValues = array_fill_keys($dishsalesWithoutColumns, 0);

            foreach ($data['dish_saleswithoutservice'] as $dsw) {

                if (!isset($dsw['cp']['dish_type'])) continue;

                $type = (int)$dsw['cp']['dish_type'];
                $key  = 'W/O SC - ' . ($dishTypeMap[$type] ?? $type);

                if (array_key_exists($key, $dishsalesWithoutValues)) {
                    $dishsalesWithoutValues[$key] = round((float)$dsw[0]['total_amount'], 2);
                }
            }

            foreach ($dishsalesWithoutColumns as $col) {
                $sheet->setCellValueByColumnAndRow($colIndex++, $row, $dishsalesWithoutValues[$col]);
            }
            // SC breakup columns
            $sc_sagg5 = 0; $sc_sagg189 = 0;
            foreach ($data['sales'] as $s) {
                if ($s['final']['tax_percentage'] == 5) $sc_sagg5 += $s['final']['value'];
                elseif ($s['final']['tax_percentage'] == 18.9) $sc_sagg189 += $s['final']['value'];
            }
            $sc_bfv = 0; $sc_blq = 0;
            foreach ($data['sc_base_sales'] as $b) {
                $dt = (int)$b['cp']['dish_type'];
                if ($dt == 0 || $dt == 1) $sc_bfv += $b[0]['base_amount'];
                elseif ($dt == 2) $sc_blq += $b[0]['base_amount'];
            }
            $sc_gv = round($sc_sagg5 - $sc_bfv, 2);
            $sc_vv = round($sc_sagg189 - $sc_blq, 2);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv + $sc_vv, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $sc_gv);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, $sc_vv);
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv * 0.025, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_gv * 0.025, 2));
            $sheet->setCellValueByColumnAndRow($colIndex++, $row, round($sc_vv * 0.189, 2));

            $row++;
        }
    
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="DSR_REPORT.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    public function dsr_reportpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $date_range= $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $cashier_id=$this->request->data['cashier'];
            if($cashier_id){
                $cashiernames=$this->Location->find('first',array('conditions'=>array('id'=>$cashier_id)));
                $cashiername=$cashiernames['Location']['name'];

                $where_location=" and store_id=$cashier_id";
                
                $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                
                $onlinepayments = $this->Order_payment->query("
                    SELECT 
                        type_value,
                        SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE 
                        type = 11 and
                         status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                    GROUP BY type_value
                ");
                
                $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round,SUM(other_taxes) AS other_taxes FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                
                $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
            
                $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                
                $net_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
                
                $ncnet_amount_query = $this->Order_transaction->query("
                    SELECT 
                        round(SUM(ot.price)
                        - IFNULL(SUM(ot.discount), 0),2) AS net_amount
                    FROM order_transactions ot
                    WHERE 
                        ot.status = 2
                        AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                        AND ot.reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                ");
    
                $dish_sales = $this->Order_orderhistory->query("
                    SELECT
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp
                        ON cp.id = ooh.product_id
                    INNER JOIN (
                        SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                    WHERE
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id
                            FROM order_payments
                            WHERE type = 7
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $dish_saleswithoutservice = $this->Order_orderhistory->query("
                    SELECT 
                        cp.dish_type,
                        SUM(ooh.quantity) AS total_qty,
                        ROUND(
                            SUM(
                                (ooh.price * ooh.quantity) 
                                * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                            ), 
                        2) AS total_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp 
                        ON cp.id = ooh.product_id
                    LEFT JOIN (
                        SELECT 
                            orderhistory_id,
                            MAX(discount_percentage) AS discount_percentage
                        FROM order_tax
                        WHERE status != 0
                        GROUP BY orderhistory_id
                    ) ot ON ot.orderhistory_id = ooh.id
                    WHERE 
                        ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )
                    GROUP BY cp.dish_type
                    ORDER BY cp.dish_type DESC
                ");

                $sc_base_sales = $this->Order_orderhistory->query("
                    SELECT cp.dish_type,
                        ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                    FROM order_orderhistories ooh
                    INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                    LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                    WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                        AND ooh.status = 2 $where_location
                        AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                    GROUP BY cp.dish_type
                ");
                
                $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id NOT IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                        
                $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                        reference_id IN (
                            SELECT reference_id 
                            FROM order_payments 
                            WHERE type = 7 
                              AND status = 2 $where_location
                        )");
                
                $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
            }else{
                $cashiername='All Stores';
                if($userRole!='admin' ){
                    $where_location=" AND store_id IN (" . $userLocationId . ")";
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id $where_location),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' $where_location");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime' $where_location
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(price) AS price,SUM(round) AS round,SUM(other_taxes) AS other_taxes FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' $where_location and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 $where_location");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by tax_id");
                    
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime' $where_location
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                    ");
    
                    $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                    ");

                    $dish_saleswithoutservice = $this->Order_orderhistory->query("
                        SELECT 
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(
                                SUM(
                                    (ooh.price * ooh.quantity)
                                    * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                                ),
                            2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp 
                            ON cp.id = ooh.product_id
                        LEFT JOIN (
                            SELECT 
                                orderhistory_id,
                                MAX(discount_percentage) AS discount_percentage
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot ON ot.orderhistory_id = ooh.id
                        WHERE 
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                    ");
                    
                    $sc_base_sales = $this->Order_orderhistory->query("
                        SELECT cp.dish_type,
                            ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                        LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                        WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2 $where_location
                            AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2 $where_location)
                        GROUP BY cp.dish_type
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 $where_location AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2 $where_location
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id FROM `order_orderhistories` WHERE  status!=0 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2 $where_location) $where_location) $where_location GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                
                }else{
                    
                    $payments = $this->Order_payment->query("SELECT SUM(amount) as total_amount,SUM(IF(type=1,amount,0)) AS cash,SUM(IF(type=10,amount,0)) AS hold,SUM(IF(type=2,amount,0)) AS card,SUM(IF(type=9,amount,0)) AS online,SUM(IF(type=6,amount,0)) AS upi,SUM(IF(type=7,amount,0)) AS no_charge_with_tax,SUM(IF(type=7,round(amount-(SELECT SUM(total_tax) from order_transactions WHERE status!=0 and reference_id=order_payments.reference_id),2),0)) AS no_charge,SUM(IF(type=8,amount,0)) AS storecard FROM `order_payments` where status=2 and created BETWEEN '$startDatetime' AND '$endDatetime' ");
                    
                    $onlinepayments = $this->Order_payment->query("
                        SELECT 
                            type_value,
                            SUM(amount) AS total_amount
                        FROM order_payments
                        WHERE 
                            type = 11 and
                             status=2 and created BETWEEN '$startDatetime' and '$endDatetime'
                        GROUP BY type_value
                    ");
                    
                    $transactions = $this->Order_transaction->query("SELECT COUNT(id) as total_count,SUM(pax) AS pax,SUM(total_tax) AS total_tax,SUM(servicecharge) AS servicecharge,SUM(discount) AS discount,SUM(delivery_charge) AS delivery_charge,SUM(packing_charge) AS packing_charge,SUM(amount) AS amount,SUM(round) AS round,SUM(price) AS price,SUM(other_taxes) AS other_taxes  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsnc = $this->Order_transaction->query("SELECT SUM(total_tax) AS total_tax FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2)");
                    
                    $transactionsubtotal = $this->Order_transaction->query("SELECT SUM(price) AS price,SUM(discount) AS discount  FROM `order_transactions` where  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2");
                
                    $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE  created BETWEEN '$startDatetime' AND '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by tax_id");
                
                    $net_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
                    
                    $ncnet_amount_query = $this->Order_transaction->query("
                        SELECT 
                            SUM(ot.price)
                            - IFNULL(SUM(ot.discount), 0) AS net_amount
                        FROM order_transactions ot
                        WHERE 
                            ot.status = 2
                            AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ot.reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                    ");
    
                    $dish_sales = $this->Order_orderhistory->query("
                        SELECT
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(SUM(ot_tax.taxable_price), 2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp
                            ON cp.id = ooh.product_id
                        INNER JOIN (
                            SELECT orderhistory_id, MAX(taxable_price) AS taxable_price
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot_tax ON ot_tax.orderhistory_id = ooh.id
                        WHERE
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id
                                FROM order_payments
                                WHERE type = 7
                                  AND status = 2
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                    ");

                    $dish_saleswithoutservice = $this->Order_orderhistory->query("
                        SELECT 
                            cp.dish_type,
                            SUM(ooh.quantity) AS total_qty,
                            ROUND(
                                SUM(
                                    (ooh.price * ooh.quantity)
                                    * (1 - IFNULL(ot.discount_percentage, 0) / 100)
                                ),
                            2) AS total_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp 
                            ON cp.id = ooh.product_id
                        LEFT JOIN (
                            SELECT 
                                orderhistory_id,
                                MAX(discount_percentage) AS discount_percentage
                            FROM order_tax
                            WHERE status != 0
                            GROUP BY orderhistory_id
                        ) ot ON ot.orderhistory_id = ooh.id
                        WHERE 
                            ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )
                        GROUP BY cp.dish_type
                        ORDER BY cp.dish_type DESC
                    ");
                    
                    $sc_base_sales = $this->Order_orderhistory->query("
                        SELECT cp.dish_type,
                            ROUND(SUM(ooh.price * ooh.quantity * (1 - IFNULL(ot_d.discount_percentage, 0) / 100)), 2) AS base_amount
                        FROM order_orderhistories ooh
                        INNER JOIN catalog_product cp ON cp.id = ooh.product_id
                        LEFT JOIN (SELECT orderhistory_id, MAX(discount_percentage) AS discount_percentage FROM order_tax WHERE status != 0 GROUP BY orderhistory_id) ot_d ON ot_d.orderhistory_id = ooh.id
                        WHERE ooh.created BETWEEN '$startDatetime' AND '$endDatetime'
                            AND ooh.status = 2
                            AND ooh.reference_id NOT IN (SELECT reference_id FROM order_payments WHERE type = 7 AND status = 2)
                        GROUP BY cp.dish_type
                    ");
                    
                    $taxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $nontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id NOT IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $nctaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_taxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage != 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                            
                    $ncnontaxable = $this->Order_orderhistory->query("SELECT sum(total_price) as total_nontaxable FROM `order_orderhistories` WHERE  status = 2 and created BETWEEN '$startDatetime' AND '$endDatetime' and total_tax_percentage = 0 AND
                            reference_id IN (
                                SELECT reference_id 
                                FROM order_payments 
                                WHERE type = 7 
                                  AND status = 2
                            )");
                    
                    $sales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id NOT IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                    
                    $ncsales = $this->Order_tax->query("SELECT kds,kds_name,value,tax_percentage from (SELECT SUM(tax_percentage) as tax_percentage,kds,kds_name ,round(taxable_price,2) as value FROM (SELECT tax_percentage,tax_id,kds,(select name from pos_printers where kds=order_tax.kds) as kds_name,round(SUM(taxable_price),2) as taxable_price,sum(tax_value) as tax_value FROM `order_tax` WHERE created BETWEEN '$startDatetime' and '$endDatetime' and status=2 and reference_id IN (SELECT reference_id from order_payments WHERE type=7 and status=2) GROUP by kds,tax_id) as sub GROUP by kds,tax_value) as final GROUP by kds,tax_percentage");
                }
            }            
            
            $datas=array();
            $taxesarr=array();
            $salesarr=array();
            $ncsalesarr=array();
            $dishsalesarr=array();
            $onlinepaymentsarr=array();

            $datas[]=array(
                'cashier'=>$cashiername,
                'total_collection'=>round($payments[0][0]['total_amount']-$payments[0][0]['no_charge_with_tax'],2),
                'cash'=>round($payments[0][0]['cash'],2),
                'card'=>round($payments[0][0]['card'],2),
                'online'=>round($payments[0][0]['online'],2),
                'upi'=>round($payments[0][0]['upi'],2),
                'hold'=>round($payments[0][0]['hold'],2),
                'storecard'=>round($payments[0][0]['storecard'],2),
                'no_charge'=>round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'],2),
                'no_charge_with_tax'=>round($payments[0][0]['no_charge_with_tax'],2),
                'subtotal'=>round($transactionsubtotal[0][0]['price'],2),
                'discount'=>round($transactionsubtotal[0][0]['discount'],2),
                'taxable_amount'=>round($taxable[0][0]['total_taxable'],2),
                'nontaxable_amount'=>round($nontaxable[0][0]['total_nontaxable'],2),
                'nctaxable_amount'=>round($nctaxable[0][0]['total_taxable'],2),
                'ncnontaxable_amount'=>round($ncnontaxable[0][0]['total_nontaxable'],2),
                'service_charge'=>round($transactions[0][0]['servicecharge'],2),
                'delivery_charge'=>round($transactions[0][0]['delivery_charge'],2),
                'packing_charge'=>round($transactions[0][0]['packing_charge'],2),
                'net_sale'=>round($net_amount_query[0][0]['net_amount'],2),
                'ncnet_sale'=>round($ncnet_amount_query[0][0]['net_amount'],2),
                'total_tax'=>round($transactions[0][0]['total_tax'],2),
                'nctotal_tax'=>round($transactionsnc[0][0]['total_tax'],2),
                'bill_count'=>round($transactions[0][0]['total_count'],2),
                'net_amount'=>round($transactions[0][0]['amount'],2),
                'round'=>round($transactions[0][0]['round'],2),
                'pax'=>round($transactions[0][0]['pax'],2),
				'other_taxes' => round($transactions[0][0]['other_taxes'], 2)
            );
        
            foreach($onlinepayments as $onlinepayment){
                $onlinepaymentsarr[]=array(
                    'type'=>$onlinepayment['order_payments']['type_value'],
                    'amount'=>$onlinepayment[0]['total_amount']
                );
            }
            
            foreach($taxes as $tax){
                $taxesarr[]=array(
                    'tax_name'=>$tax['order_tax']['tax_name'].'('.$tax['order_tax']['tax_percentage'].'%)',
                    'tax_value'=>$tax[0]['tax_value']
                );
            }
			if (!empty($datas[0]['other_taxes']) && $datas[0]['other_taxes'] > 0) {
				$taxesarr[] = array(
					'tax_name'  => 'Other Charges Tax',
					'tax_value' => $datas[0]['other_taxes']
				);
			}
            
            foreach($sales as $sale){
                // print_r($sale);exit;
                $salesarr[]=array(
                    'kds'=>$sale['final']['kds_name'],
                    'kds_value'=>round($sale['final']['value'],2),
                    'tax_percentage'=>$sale['final']['tax_percentage'],
                );
            }
            
            foreach($ncsales as $ncsale){
                // print_r($sale);exit;
                $ncsalesarr[]=array(
                    'kds'=>$ncsale['final']['kds_name'],
                    'kds_value'=>round($ncsale['final']['value'],2),
                    'tax_percentage'=>$ncsale['final']['tax_percentage'],
                );
            }
            
            foreach($dish_sales as $dish_sale){
                // print_r($sale);exit;
                $dishsalesarr[]=array(
                    'dish_type'=>$dish_sale['cp']['dish_type'],
                    'total_amount'=>round($dish_sale['0']['total_amount'],2)
                );
            }

            $dishsaleswithoutservicearr = [];

            foreach($dish_saleswithoutservice as $dish_sale){
                $dishsaleswithoutservicearr[] = array(
                    'dish_type'=>$dish_sale['cp']['dish_type'],
                    'total_amount'=>round($dish_sale[0]['total_amount'],2)
                );
            }

            // SC breakup for PDF
            $pdf_sagg5 = 0; $pdf_sagg189 = 0;
            foreach($salesarr as $s) {
                if ($s['tax_percentage'] == 5) $pdf_sagg5 += $s['kds_value'];
                elseif ($s['tax_percentage'] == 18.9) $pdf_sagg189 += $s['kds_value'];
            }
            $pdf_bfv = 0; $pdf_blq = 0;
            foreach($sc_base_sales as $b) {
                $dt = (int)$b['cp']['dish_type'];
                if ($dt == 0 || $dt == 1) $pdf_bfv += $b[0]['base_amount'];
                elseif ($dt == 2) $pdf_blq += $b[0]['base_amount'];
            }
            $pdf_sc_gst = round($pdf_sagg5 - $pdf_bfv, 2);
            $pdf_sc_vat = round($pdf_sagg189 - $pdf_blq, 2);
            $scbreakuparr = array(
                'sc_total'   => round($pdf_sc_gst + $pdf_sc_vat, 2),
                'sc_gst'     => $pdf_sc_gst,
                'sc_vat'     => $pdf_sc_vat,
                'sgst_on_sc' => round($pdf_sc_gst * 0.025, 2),
                'cgst_on_sc' => round($pdf_sc_gst * 0.025, 2),
                'vat_on_sc'  => round($pdf_sc_vat * 0.189, 2),
            );
            
            $this->set(compact('startdate','enddate','datas','taxesarr','salesarr','ncsalesarr','dishsalesarr','dishsaleswithoutservicearr','scbreakuparr','onlinepaymentsarr'));
        }
    }
   
    public function card_report() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
    
        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
            
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $card_no= $this->request->data['Search']['card_no'];
        
        $cards = $this->Cardtracking->query("SELECT txnid,type,amount,created,purpose FROM `cardtracking` WHERE cardnumber='$card_no' and created between '$startDatetime' and '$endDatetime' order by id desc");
    
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
    
        $this->set(compact('cards'));
        
    }
    
    public function card_reportexport() {
        $date_range= $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate= date('Y-m-d', strtotime($start_date));
        $enddate= date('Y-m-d', strtotime($end_date));

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $card_no= $_GET['id'];
        $cards = $this->Cardtracking->query("SELECT txnid,type,amount,created,purpose FROM `cardtracking` WHERE cardnumber='$card_no' and created between '$startDatetime' and '$endDatetime' order by id desc");
        
        $datas=array();
        foreach($cards as $card){
            $datas[]=array(
                'txnid'=>$card['cardtracking']['txnid'],
                'type'=>$card['cardtracking']['type'],
                'purpose'=>$card['cardtracking']['purpose'],
                'amount'=>$card['cardtracking']['amount'],
                'created'=>$card['cardtracking']['created']
            );
        }
             
        App::import('Vendor', 'PHPExcel/PHPExcel');
           error_reporting(0);
           ini_set('display_errors', TRUE);
           ini_set('display_startup_errors', TRUE);
           if (PHP_SAPI == 'cli')
                die('This example should only be run from a Web Browser');
           $objPHPExcel = new PHPExcel();
           // Set document properties
           $objPHPExcel->getProperties()->setCreator("Aether")
           ->setLastModifiedBy("Aether")
           ->setTitle("Office 2007 XLSX Aether Document")
           ->setSubject("Office 2007 XLSX Aether Document")
           ->setDescription("Aether Export Data File.")
           ->setKeywords("office 2007 openxml php")
           ->setCategory("AetherPos Export Data File");
           // Add some data
           $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', '   ' .'CARD REPORT OF '.$card_no);
           
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', 'SR. NO.');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B3', 'Txn id');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C3', 'Type');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D3', 'Purpose');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E3', 'Amount');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F3', 'Created');
            $objPHPExcel->getActiveSheet()->getStyle("A1:F3")->getFont()->setBold(true);
            $objPHPExcel->getActiveSheet()->mergeCells('A1:F1');
            
            $baseRow = 3;
            $r=1;
            
            foreach($datas as $dat){
                  
                    if($dat['type']==1){
                        $type='credit';
                    }elseif($dat['type']==2){
                        $type='debit';
                    }elseif($dat['type']==3){
                        $type='security';
                    }else{
                        $type='refund';
                    }
                    
                    if($dat['purpose']=='card_charge'){
                        $purpose='card charge';
                    }elseif($dat['purpose']=='transferfrom'){
                        $purpose='transfer from';
                    }elseif($dat['purpose']=='transferto'){
                        $purpose='transfer to';
                    }else{
                        $purpose=$dat['purpose'];
                    }
                    
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.($baseRow + $r),$r);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B'.($baseRow + $r),$dat['txnid']);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C'.($baseRow + $r),$type);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D'.($baseRow + $r),$purpose);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E'.($baseRow + $r),abs($dat['amount']));
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F'.($baseRow + $r),$dat['created']);
                                  
                           $r++;
                   
                }
                
                  //$r++;
                 
               
               //$objPHPExcel->getActiveSheet()->removeRow($baseRow-1,1);
               //$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'Hello');
               // Miscellaneous glyphs, UTF-8
               // Rename worksheet
               $objPHPExcel->getActiveSheet()->setTitle('Export Data');
               // Set active sheet index to the first sheet, so Excel opens this as the first sheet
               $objPHPExcel->setActiveSheetIndex(0);
               // Redirect output to a client’s web browser (Excel5)
               header('Content-Type: application/vnd.ms-excel');
               header('Content-Disposition: attachment;filename="'.'CARD REPORT.xls"');
               header('Cache-Control: max-age=0');
               // If you're serving to IE 9, then the following may be needed
               header('Cache-Control: max-age=1');
               // If you're serving to IE over SSL, then the following may be needed
               header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
               header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
               header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
               header ('Pragma: public'); // HTTP/1.0
               $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
               $objWriter->save('php://output');
               exit;
               
    }
    
    public function card_reportpdf()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "login";
        if($this->request->is('post', 'put'))
        {
            $card_no= $this->request->data['cardno'];
            $date_range= $this->request->data['sdate'];
            
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));

            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $cards = $this->Cardtracking->query("SELECT cardnumber,txnid,purpose,type,amount,created FROM `cardtracking` WHERE cardnumber='$card_no' and created between '$startDatetime' and '$endDatetime' order by id desc");
            $datas=array();
            foreach($cards as $card){
                $datas[]=array(
                    'card_no'=>$card['cardtracking']['cardnumber'],
                    'txnid'=>$card['cardtracking']['txnid'],
                    'purpose'=>$card['cardtracking']['purpose'],
                    'type'=>$card['cardtracking']['type'],
                    'amount'=>$card['cardtracking']['amount'],
                    'created'=>$card['cardtracking']['created']
                );
            }
              $this->set(compact('card_no','datas'));
        }
    }
    
    public function cashier_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
          
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $startDatetime = $startDateFormatted . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($endDateFormatted . ' +1 day')) . ' ' . shiftend;

        $locationCondition = '';
        if ($userRole !== 'admin') {
            $locationCondition = "AND id IN (SELECT user_id from user_locations WHERE status=1 and location_id IN (" . $userLocationId . "))";
        }
        $users = $this->User->query("SELECT *,(SELECT GROUP_CONCAT(name) FROM `user_modules` WHERE user_id=users.id and status=1) as module,(SELECT GROUP_CONCAT(location_name) FROM `user_locations` WHERE user_id=users.id and status=1) as locations FROM `users` WHERE role IN ('cashier','manager') and created BETWEEN '$startDatetime' and '$endDatetime' $locationCondition order by id desc");
        
        $moduleLabels=moduleswithlabel;
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));
        $this->set(compact('moduleLabels'));

    }
        
    public function subadmin_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
          
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $locationCondition = '';
        if ($userRole !== 'admin') {
            $locationCondition = "AND id IN (SELECT user_id from user_locations WHERE status=1 and location_id IN (" . $userLocationId . "))";
        }

        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->User->query("SELECT *,(SELECT GROUP_CONCAT(name) FROM `user_modules` WHERE user_id=users.id and status=1) as module,(SELECT GROUP_CONCAT(location_name) FROM `user_locations` WHERE user_id=users.id and status=1) as locations FROM `users` WHERE role IN ('subadmin','kitchen') $locationCondition and created BETWEEN '$startDatetime' and '$endDatetime' order by id desc");
        
        $moduleLabels=subadminmoduleswithlabel;
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));
        $this->set(compact('moduleLabels'));

    }
        
    public function cashier_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['user_id'];
    
            // Update user status
            $this->User->id = $userId;
            $newStatus = $this->User->field('status') == 1 ? 0 : 1;
            if ($this->User->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function cancel_booking() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $id = $this->request->data['_id'];
    
            // Update user status
            $this->Online_booking->id = $id;
            if ($this->Online_booking->save(['status' => 0,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function subadmin_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['user_id'];
    
            // Update user status
            $this->User->id = $userId;
            $newStatus = $this->User->field('status') == 1 ? 0 : 1;
            if ($this->User->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function card_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            

            $currentStatus = $this->Card->field('status', ['id' => $Id]);
            $newStatus = in_array($currentStatus, [1, 2]) ? 0 : 1;
            
            $this->Card->id = $Id;
            
            if ($this->Card->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function category_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_category->id = $Id;
            $newStatus = $this->Catalog_category->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_category->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function subcategory_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_subcategory->id = $Id;
            $newStatus = $this->Catalog_subcategory->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_subcategory->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function tax_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_tax->id = $Id;
            $newStatus = $this->Catalog_tax->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_tax->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function unit_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_unit->id = $Id;
            $newStatus = $this->Catalog_unit->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_unit->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function product_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_product->id = $Id;
            $newStatus = $this->Catalog_product->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_product->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function sku_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Inventory_sku->id = $Id;
            $newStatus = $this->Inventory_sku->field('status') == 1 ? 0 : 1;
            
            if ($this->Inventory_sku->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function semifinished_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Inventory_semifinished->id = $Id;
            $newStatus = $this->Inventory_semifinished->field('status') == 1 ? 0 : 1;
            
            if ($this->Inventory_semifinished->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                $this->Inventory_semifinished_tax->updateAll(
                    [
                        'status' => $newStatus,
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['product_id' => $Id]
                );

                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function vendor_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['_id'];
    
            // Update user status
            $this->Inventory_vendor->id = $userId;
            $newStatus = $this->Inventory_vendor->field('status') == 1 ? 0 : 1;
            if ($this->Inventory_vendor->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                $this->Inventory_vendor_service_area->updateAll(
                    [
                        'status' => $newStatus,
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['vendor_id' => $userId]
                );
                
                $this->Inventory_vendor_sku_served->updateAll(
                    [
                        'status' => $newStatus,
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['vendor_id' => $userId]
                );

                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function indent_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['_id'];
    
            // Update user status
            $this->Inventory_internal_indent->id = $userId;
            $newStatus = $this->Inventory_internal_indent->field('status') == 1 ? 0 : 1;
            if ($this->Inventory_internal_indent->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function location_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Location->id = $Id;
            $newStatus = $this->Location->field('status') == 1 ? 0 : 1;
            
            if ($this->Location->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function table_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Order_table->id = $Id;
            
            $currentStatus = $this->Order_table->field('status', ['id' => $Id]);
            $newStatus = in_array($currentStatus, [1, 2,3]) ? 0 : 1;
            

            if ($this->Order_table->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function coupon_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Coupon->id = $Id;
            
            $newStatus = $this->Coupon->field('status') == 1 ? 0 : 1;
            if ($this->Coupon->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function remove_subcategory() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_subcategory->id = $Id;
            if ($this->Catalog_subcategory->save(['status' => 0,'sync' => 0,'local_sync' => 0])) {
                
                $categoryid = $this->Catalog_subcategory->query("SELECT cat_id FROM catalog_subcategory where id=$Id");
                $cat_id=$categoryid['0']['catalog_subcategory']['cat_id'];
                
                $subcategorychk=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$cat_id and status=1");
                if($subcategorychk){
                    $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$cat_id");
                }else{
                    $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=0,sync = 0,local_sync=0 WHERE id=$cat_id");
                }
                
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function category_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Catalog_category->find('all', array(
            'conditions' => array('created BETWEEN ? AND ?' => array($startDatetime , $endDatetime)
            ),
            'order' => array(
                'id' => 'DESC' // Order by the 'created' field in ascending order
            )
        ));
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function subcategory_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Catalog_subcategory->query("SELECT *,(SELECT name FROM catalog_category where id=catalog_subcategory.cat_id) as cat_name FROM catalog_subcategory where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function card_list()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Card->find('all', array(
            'conditions' => array(
                'Card.created BETWEEN ? AND ?' => array($startDatetime,$endDatetime)
            ),
            'order' => array(
                'Card.id' => 'DESC' // Order by the 'created' field in ascending order
            )
        ));
        
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users'));

    }   
    
    public function card_listexport()
    {
        $date_range= $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate= date('Y-m-d', strtotime($start_date));
        $enddate= date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cards = $this->Card->find('all', array(
            'conditions' => array(
                'Card.created BETWEEN ? AND ?' => array($startDatetime, $endDatetime)
            ),
            'order' => array(
                'Card.id' => 'DESC' // Order by the 'created' field in ascending order
            )
        ));
        
        $datas=array();
        
        foreach($cards as $card){
            $datas[]=array(
                'cardnumber'=>$card['Card']['cardnumber'],
                'cardbalance'=>$card['Card']['cardbalance'],
                'name'=>$card['Card']['name'],
                'mobile'=>$card['Card']['mobile'],
                'status'=>$card['Card']['status'],
                'created'=>$card['Card']['created']
            );
        }
             
        App::import('Vendor', 'PHPExcel/PHPExcel');
           error_reporting(0);
           ini_set('display_errors', TRUE);
           ini_set('display_startup_errors', TRUE);
           if (PHP_SAPI == 'cli')
                die('This example should only be run from a Web Browser');
           $objPHPExcel = new PHPExcel();
           // Set document properties
           $objPHPExcel->getProperties()->setCreator("Aether")
           ->setLastModifiedBy("Aether")
           ->setTitle("Office 2007 XLSX Aether Document")
           ->setSubject("Office 2007 XLSX Aether Document")
           ->setDescription("Aether Export Data File.")
           ->setKeywords("office 2007 openxml php")
           ->setCategory("AetherPos Export Data File");
           // Add some data
           $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', '   ' .'CARD LIST FROM '.$startdate.' TO '.$enddate);
           
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', 'SR. NO.');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B3', 'Card No.');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C3', 'Card Balance');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D3', 'Name');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E3', 'Mobile');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F3', 'Status');
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G3', 'Created');
            $objPHPExcel->getActiveSheet()->getStyle("A1:G3")->getFont()->setBold(true);
            $objPHPExcel->getActiveSheet()->mergeCells('A1:G1');
            
            $baseRow = 3;
            $r=1;
            
            foreach($datas as $dat){

                  if($dat['status']==0){
                      $status='InActive';
                  }else{
                      $status='Active';
                  }
                  
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.($baseRow + $r),$r);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B'.($baseRow + $r),$dat['cardnumber']);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C'.($baseRow + $r),$dat['cardbalance']);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D'.($baseRow + $r),$dat['name']);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E'.($baseRow + $r),$dat['mobile']);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F'.($baseRow + $r),$status);
                  $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G'.($baseRow + $r),$dat['created']);
                                  
                           $r++;
                   
                }
                
                  //$r++;
                 
               
               //$objPHPExcel->getActiveSheet()->removeRow($baseRow-1,1);
               //$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'Hello');
               // Miscellaneous glyphs, UTF-8
               // Rename worksheet
               $objPHPExcel->getActiveSheet()->setTitle('Export Data');
               // Set active sheet index to the first sheet, so Excel opens this as the first sheet
               $objPHPExcel->setActiveSheetIndex(0);
               // Redirect output to a client’s web browser (Excel5)
               header('Content-Type: application/vnd.ms-excel');
               header('Content-Disposition: attachment;filename="'.'CARD LIST.xls"');
               header('Cache-Control: max-age=0');
               // If you're serving to IE 9, then the following may be needed
               header('Cache-Control: max-age=1');
               // If you're serving to IE over SSL, then the following may be needed
               header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
               header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
               header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
               header ('Pragma: public'); // HTTP/1.0
               $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
               $objWriter->save('php://output');
               exit;
               
        
        

    }   
    
    public function profile()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$this->Session->read('Auth.User.empID');
        $userdetail=$this->Employee->find('first',array('conditions'=>array('Employee.empID'=>$id)));
        $this->set('userdetail', $userdetail);
    }   
    
    public function create_cashier()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? '';
        
        $conditions = ['status' => 1];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $ids = array_filter(array_map('trim', explode(',', $userLocationId))); // clean IDs
            if (!empty($ids)) {
                $conditions['id IN'] = $ids;
            }
        }
        
        $modules=moduleswithlabel;
        $this->set(compact('modules'));
        
        $locations=$this->Location->find('all',['conditions' => $conditions]);
        $this->set(compact('locations'));
        
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_cashier'));
            }
            
            $mobile = $this->data['User']['mobile'];
            $username = $this->data['User']['username'];
        
            $userdetail=$this->User->find('first',array('conditions'=>array('User.username'=>$username)));
            if($userdetail){
                $this->Flash->error(__('Username already exist'));
                return $this->redirect(array('action' => 'create_cashier'));
            }
            $password =$this->data['User']['password'];
            $password = AuthComponent::password($password);
            
            $modules=moduleswithlabel;
            $checkedModules = [];
            
            $bill_location =$this->data['User']['bill_location'];
            $loc_type =$this->data['User']['loc_type'];
            
            $role =$this->data['User']['role'];
            $settlement =$this->data['User']['settlement'];
            
            if($role=='manager'){
                $pin =$this->data['User']['pin'] ?? 0;
            }else{
                $pin = 0;
            }
            
            if($loc_type==0){
                $location_ids =[];
            }else{
                $location_ids =$this->data['User']['location'];
            }

            $locationdetail = $this->Location->find('first', array(
                                'conditions' => array('Location.id' => $bill_location)
                            ));
                
            if (!empty($locationdetail)) {
                $locationnamee = $locationdetail['Location']['name'];
            }
            
            $data['User']=array(
                'name'=>$name,
                'username'=>$username,
                'password'=>$password,
                'mobile'=>$mobile,
                'can_settlement'=>$settlement,
                'role'=>$role,
                'pin'=>$pin,
                'location_id'=>$bill_location,
                'location_name'=>$locationnamee,
                'sync'=>0,
                'local_sync'=>0
            );
            
            
            if($this->User->saveAll($data['User']))
            {
                $lastInsertedID = $this->User->id;
                foreach($location_ids as $location_id){
                    $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
                    $locationname=$locationdetail['Location']['name'];
                    
                    $isBill = (!empty($bill_location) && (
                        (is_array($bill_location) && in_array($location_id, $bill_location)) ||
                        (!is_array($bill_location) && $bill_location == $location_id)
                   )) ? 1 : 0;
                   
                    $data['User_location']=array(
                        'user_id'=>$lastInsertedID,
                        'user_name'=>$username,
                        'location_id'=>$location_id,
                        'location_name'=>$locationname,
                        'billing_location'=>$isBill,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                
                    if($this->User_location->saveAll($data['User_location']))
                    {

                    }else{
                        $this->Flash->error(__('The user Locations could not be saved. Please, try again.'));
                    }
                }
                
                if (!empty($bill_location)) {
                    $billLocations = is_array($bill_location) ? $bill_location : array($bill_location);
                
                    foreach ($billLocations as $billLoc) {
                        if (!in_array($billLoc, $location_ids)) {
                            $locationdetail = $this->Location->find('first', array(
                                'conditions' => array('Location.id' => $billLoc)
                            ));
                
                            if (!empty($locationdetail)) {
                                $locationname = $locationdetail['Location']['name'];
                
                                $data['User_location'] = array(
                                    'user_id'       => $lastInsertedID,
                                    'user_name'     => $username,
                                    'location_id'   => $billLoc,
                                    'location_name' => $locationname,
                                    'billing_location' => 1,
                                    'sync'=>0,
                                    'local_sync'=>0
                                );
                
                                $this->User_location->create();
                                if (!$this->User_location->save($data['User_location'])) {
                                    $this->Flash->error(__('The extra bill Location could not be saved. Please, try again.'));
                                }
                            }
                        }
                    }
                }
                
                foreach ($modules as $moduleKey => $moduleLabel) {
                    if (isset($this->data['User'][$moduleKey]) && $this->data['User'][$moduleKey]) {
                        $checkedModules[$moduleKey] = $this->data['User'][$moduleKey];
                        $data['User_module']=array(
                            'name'=>$moduleKey,
                            'user_id'=>$lastInsertedID,
                            'sync'=>0,
                            'local_sync'=>0
                        );
                        if($this->User_module->saveAll($data['User_module']))
                        {
                        }else{
                            $this->Flash->error(__('The user modules could not be saved. Please, try again.'));
                        }
                    }
                }
                
                $this->Flash->success(__('The User has been saved.'));
                return $this->redirect(array('action' => 'cashier_list'));
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        
        
    }
    
    public function create_booking()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        if ($_POST['bookdate']) {
            $bookdate=$_POST['bookdate'];
            $booktime=$_POST['booktime'];
        }else{
            $bookdate= date('Y-m-d');
            $currentHour = date('H');
            $defaultTime = '22';
            $booktime=($currentHour < 22) ? $defaultTime : $currentHour;
        }
        $newbookdate= date('d-m-Y', strtotime($bookdate));
        $this->set('bookdate', $newbookdate);
        $this->set('booktime', $booktime);
        $booking_time=$bookdate.' '.$booktime.':00:00';
        
        $adddatetime = new DateTime($booking_time);
        $adddatetime->modify('+4 hours');
        $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
        
        $subdatetime = new DateTime($booking_time);
        $subdatetime->modify('-4 hours');
        $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
        
        $tables=$this->Order_table->query("SELECT *,(SELECT id FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=order_tables.number) as bookstatus FROM `order_tables`");
        $this->set(compact('tables'));

    }
    
    public function book_now()
    {
        $this->layout = false;
        $id = $this->data['User']['id'];
        if ($id) {
            
            $bookdate = $this->data['User']['bookdate'];
            $booktime = $this->data['User']['booktime'];
            
            if($booktime==10){
                $booktime=22;    
            }
            if($booktime==11){
                $booktime=23;    
            }
            
            $booking_time=$bookdate.' '.$booktime.':00:00';
            
            $adddatetime = new DateTime($booking_time);
            $adddatetime->modify('+4 hours');
            $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
            
            $subdatetime = new DateTime($booking_time);
            $subdatetime->modify('-4 hours');
            $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
            
            $table = $this->Online_booking->query("SELECT * FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=$id");
            
            if(!$table){
                $ref_id = $this->data['User']['ref_id'];
                $pax = $this->data['User']['pax'];
                $cover_charge=$this->data['User']['cover_charge'];
                $name = $this->data['User']['name'];
                $mobile = $this->data['User']['phone'];
                $remarks = $this->data['User']['remarks'];
                $prepaid=$this->data['User']['prepaid'];
                $payment_type=1;
                if($prepaid==1){
                    $payment_type=2;
                }
                if($_POST['pay_type']){
                    $pay_type=$_POST['pay_type'];
                    if($pay_type==1){
                        $pay_type_value='cash';
                    }
                    if($pay_type==2){
                        $pay_type_value='card';
                    }
                    if($pay_type==6){
                        $pay_type_value='upi';
                    }
                }else{
                    $pay_type=0;
                    $pay_type_value='';
                }
                
                $booking_time=$bookdate.' '.$booktime.':00:00';
                $booking_time= date('Y-m-d H:i:s', strtotime($booking_time));
                $usrid = $this->Session->read('Auth.User.id');
        
                $data['Online_booking']=array(
                    'table_number'=>$id,
                    'reference_id'=>$ref_id,
                    'pax'=>$pax,
                    'cover_charge'=>$cover_charge,
                    'user_id'=>$usrid,
                    'name'=>$name,
                    'phone'=>$mobile,
                    'booking_time'=>$booking_time,
                    'payment_type'=>$payment_type,
                    'pay_option'=>$pay_type,
                    'pay_option_value'=>$pay_type_value,
                    'remarks'=>$remarks,
                    'sync'=>0,
                    'local_sync'=>0
                );
                
                if($this->Online_booking->saveAll($data['Online_booking']))
                {
                  //  $this->Order_table->query("UPDATE order_tables SET status='2' WHERE id =". $id);
            
                    $this->Flash->success(__('The Booking has been saved.'));
                    return $this->redirect(array('action' => 'create_booking'));
                }else{
                    $this->Flash->error(__('Table not booked,try again'));
                    return $this->redirect(array('action' => 'create_booking'));
                }
            }else{
                $this->Flash->error(__('Table Already Booked!! kindly try again with another table !'));
                return $this->redirect(array('action' => 'create_booking'));
            }
        }else{
            if($this->request->is('ajax'))
            {
                $bookdate = $this->request->data['bookdate'];
                $booktime = $this->request->data['booktime'];
                $number=$this->request->data['number'];
                // $this->set(compact('bookdate'));
                // $this->set(compact('booktime'));
                
                $newbookdate= date('d-m-Y', strtotime($bookdate));
                $this->set('bookdate', $newbookdate);
                $this->set('booktime', $booktime);
                $booking_time=$bookdate.' '.$booktime.':00:00';
                // print_r($booktime);exit;
                $adddatetime = new DateTime($booking_time);
                $adddatetime->modify('+4 hours');
                $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
                
                $subdatetime = new DateTime($booking_time);
                $subdatetime->modify('-4 hours');
                $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
                
                $tablesdata=$this->Order_table->query("SELECT *,(SELECT id FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=$number) as bookstatus FROM `order_tables` where number=$number");
                if(!isset($tablesdata[0]['bookstatus'])){
                    $this->set(compact('tablesdata'));
                } else {
                    echo 'Table not Vacant!! Kindly refresh again';
                }
            } else {
                $this->Flash->error(__('Invalid Request'));
                return $this->redirect(array('action' => 'create_booking'));
            }
        }
   }
    
    public function edit_booking()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        if ($_REQUEST['id']) {
            $id=$_REQUEST['id'];
            $tabledetails=$this->Online_booking->query("SELECT * FROM `online_bookings` WHERE id=$id");
            $booking_time=$tabledetails[0]['online_bookings']['booking_time'];
            $table_number=$tabledetails[0]['online_bookings']['table_number'];
            $name=$tabledetails[0]['online_bookings']['name'];
            $phone=$tabledetails[0]['online_bookings']['phone'];
            $cover_charge=$tabledetails[0]['online_bookings']['cover_charge'];
            $pax=$tabledetails[0]['online_bookings']['pax'];
            $booking_date= date('Y-m-d', strtotime($booking_time));
            $booking_times= date('H', strtotime($booking_time));
        
            $bookdate=$booking_date;
            $booktime=$booking_times;
            
            $payment_type=$tabledetails[0]['online_bookings']['payment_type'];
            $pay_option=$tabledetails[0]['online_bookings']['pay_option'];
            $pay_option_value=$tabledetails[0]['online_bookings']['pay_option_value'];
            $remarks=$tabledetails[0]['online_bookings']['remarks'];
            $usrid = $this->Session->read('Auth.User.id');
        
            $newbookdate= date('d-m-Y', strtotime($bookdate));
            $this->set('bookdate', $newbookdate);
            $this->set('booktime', $booktime);
            $this->set('table_number', $table_number);
            $this->set('user_id', $usrid);
            $this->set('name', $name);
            $this->set('phone', $phone);
            $this->set('cover_charge', $cover_charge);
            $this->set('pax', $pax);
            $this->set('booking_id', $id);
            $this->set('payment_type', $payment_type);
            $this->set('pay_option', $pay_option);
            $this->set('pay_option_value', $pay_option_value);
            $this->set('remarks', $remarks);
         
        
            $booking_time=$bookdate.' '.$booktime.':00:00';
            
            $adddatetime = new DateTime($booking_time);
            $adddatetime->modify('+4 hours');
            $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
            
            $subdatetime = new DateTime($booking_time);
            $subdatetime->modify('-4 hours');
            $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
            
            $tables=$this->Order_table->query("SELECT *,(SELECT id FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=order_tables.number) as bookstatus FROM `order_tables` where number!=$table_number");
            $this->set(compact('tables'));
        }else{
            $this->Flash->error(__('Invalid Request'));
            return $this->redirect(array('action' => 'create_booking'));
        }
    }
    
    public function edit_book_now()
    {
        $this->layout = false;
        $id = $this->data['User']['id'];
        if ($id) {
            $bookdate = $this->data['User']['bookdate'];
            $booktime = $this->data['User']['booktime'];
            
            if($booktime==10){
                $booktime=22;    
            }
            if($booktime==11){
                $booktime=23;    
            }
            
            $booking_time=$bookdate.' '.$booktime.':00:00';
            
            $adddatetime = new DateTime($booking_time);
            $adddatetime->modify('+4 hours');
            $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
            
            $subdatetime = new DateTime($booking_time);
            $subdatetime->modify('-4 hours');
            $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
            
            $table = $this->Online_booking->query("SELECT * FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=$id");
            
            if(!$table){
                $ref_id = $this->data['User']['ref_id'];
                $pax = $this->data['User']['pax'];
                $cover_charge=$this->data['User']['cover_charge'];
                $name = $this->data['User']['name'];
                $mobile = $this->data['User']['phone'];
                $remarks = $this->data['User']['remarks'];
                $payment_type=$this->data['User']['payment_type'];
                $pay_type=$this->data['User']['pay_option'];
                $pay_type_value=$this->data['User']['pay_option_value'];
                $booking_id=$this->data['User']['booking_id'];
                // print_r($this->data['User']);exit;
                $booking_time= date('Y-m-d H:i:s', strtotime($booking_time));
        
                $data['Online_booking']=array(
                    'table_number'=>$id,
                    'reference_id'=>$ref_id,
                    'pax'=>$pax,
                    'cover_charge'=>$cover_charge,
                    'name'=>$name,
                    'phone'=>$mobile,
                    'booking_time'=>$booking_time,
                    'payment_type'=>$payment_type,
                    'pay_option'=>$pay_type,
                    'pay_option_value'=>$pay_type_value,
                    'remarks'=>$remarks,
                    'sync'=>0,
                    'local_sync' => 0
                );
                
                if($this->Online_booking->saveAll($data['Online_booking']))
                {
                    $lastInsertedID = $this->Online_booking->id;
                    $this->Online_booking->query("UPDATE online_bookings SET status='2',switch_to='$lastInsertedID',sync = 0,local_sync=0 WHERE id =". $booking_id);
            
                    $this->Flash->success(__('The Booking has been Updated.'));
                    return $this->redirect(array('action' => 'booking_list'));
                }else{
                    $this->Flash->error(__('Table not booked,try again'));
                    return $this->redirect(array('action' => 'booking_list'));
                }
            }else{
                $this->Flash->error(__('Table Already Booked!! kindly try again with another table !'));
                return $this->redirect(array('action' => 'edit_booking?id='.$booking_id));
            }
        }else{
            if($this->request->is('ajax'))
            {
                $booking_id = $this->request->data['booking_id'];
                $cover_charge = $this->request->data['cover_charge'];
                $pax = $this->request->data['pax'];
                $bookdate = $this->request->data['bookdate'];
                $booktime = $this->request->data['booktime'];
                $name = $this->request->data['name'];
                $phone = $this->request->data['phone'];
                $number=$this->request->data['number'];
                $payment_type=$this->request->data['payment_type'];
                $pay_option=$this->request->data['pay_option'];
                $pay_option_value=$this->request->data['pay_option_value'];
                $remarks=$this->request->data['remarks'];
                $prev_table_number=$this->request->data['prev_table_number'];
                $booking_id=$this->request->data['booking_id'];
                $newbookdate= date('d-m-Y', strtotime($bookdate));
                
                $this->set('bookdate', $newbookdate);
                $this->set('booktime', $booktime);
                $this->set('name', $name);
                $this->set('phone', $phone);
                $this->set('booking_id', $booking_id);
                $this->set('prev_table_number', $prev_table_number);
                $this->set('payment_type', $payment_type);
                $this->set('pay_option', $pay_option);
                $this->set('pay_option_value', $pay_option_value);
                $this->set('remarks', $remarks);
                
                $booking_time=$bookdate.' '.$booktime.':00:00';
                // print_r($booking_time);exit;
                $adddatetime = new DateTime($booking_time);
                $adddatetime->modify('+4 hours');
                $add_booking_time = $adddatetime->format('Y-m-d H:i:s');
                
                $subdatetime = new DateTime($booking_time);
                $subdatetime->modify('-4 hours');
                $sub_booking_time = $subdatetime->format('Y-m-d H:i:s');
                
                $tablesdata=$this->Order_table->query("SELECT *,(SELECT id FROM `online_bookings` WHERE booking_time BETWEEN '$sub_booking_time' and '$add_booking_time' and status=1 and table_number=$number) as bookstatus FROM `order_tables` where number=$number");
                
                if(!isset($tablesdata[0]['bookstatus'])){
                    $this->set(compact('tablesdata'));
                } else {
                    echo 'Table not Vacant!! Kindly refresh again';
                }
            } else {
                $this->Flash->error(__('Invalid Request'));
                return $this->redirect(array('action' => 'booking_list'));
            }
        }
   }
    public function create_subadmin()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? '';
        
        $conditions = ['status' => 1];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $ids = array_filter(array_map('trim', explode(',', $userLocationId))); // clean IDs
            if (!empty($ids)) {
                $conditions['id IN'] = $ids;
            }
        }
        
        $modules=subadminmoduleswithlabel;
        $this->set(compact('modules'));
        
        $locations=$this->Location->find('all',['conditions' => $conditions]);
        $this->set(compact('locations'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_cashier'));
            }
            
            $mobile = $this->data['User']['mobile'];
            $username = $this->data['User']['username'];
        
            $userdetail=$this->User->find('first',array('conditions'=>array('User.username'=>$username)));
            if($userdetail){
                $this->Flash->error(__('Username already exist'));
                return $this->redirect(array('action' => 'create_subadmin'));
            }
            $password =$this->data['User']['password'];
            $password = AuthComponent::password($password);
            
            $modules=subadminmoduleswithlabel;
            $checkedModules = [];
            
            $location_ids =$this->data['User']['location'];
            
            $role =$this->data['User']['role'];
            
            $data['User']=array(
                'name'=>$name,
                'username'=>$username,
                'password'=>$password,
                'mobile'=>$mobile,
                'role'=>$role,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->User->saveAll($data['User']))
            {
                $lastInsertedID = $this->User->id;
                foreach($location_ids as $location_id){
                    $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
                    $locationname=$locationdetail['Location']['name'];
                    
                    $data['User_location']=array(
                        'user_id'=>$lastInsertedID,
                        'user_name'=>$username,
                        'location_id'=>$location_id,
                        'location_name'=>$locationname,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    if($this->User_location->saveAll($data['User_location']))
                    {
                        $this->User->query("UPDATE users SET location_id ='$location_id',location_name='$locationname',sync = 0,local_sync=0 WHERE id =". $lastInsertedID);
                    }else{
                        $this->Flash->error(__('The user Locations could not be saved. Please, try again.'));
                    }
                }
                
                foreach ($modules as $moduleKey => $moduleLabel) {
                    if (isset($this->data['User'][$moduleKey]) && $this->data['User'][$moduleKey]) {
                        $checkedModules[$moduleKey] = $this->data['User'][$moduleKey];
                        $data['User_module']=array(
                            'name'=>$moduleKey,
                            'user_id'=>$lastInsertedID,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        if($this->User_module->saveAll($data['User_module']))
                        {
                        }else{
                            $this->Flash->error(__('The user modules could not be saved. Please, try again.'));
                        }
                    }
                }
                
                $this->Flash->success(__('The User has been saved.'));
                return $this->redirect(array('action' => 'subadmin_list'));
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        
    }
    
    public function edit_cashier()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        
        if ($this->data['User']['id']!='') {
          //  print_r($this->data['User']);exit;
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_cashier?id='.$id));
            }
            
            $mobile = $this->data['User']['mobile'];
            $password = $this->data['User']['password'];
            $userdetails=$this->User->find('first',array('conditions'=>array('User.id'=>$id)));
            $username=$userdetails['User']['username'];
            
            
            $location_ids =$this->data['User']['location'];
            
            $role =$this->data['User']['role'];
            $settlement=$this->data['User']['settlement'];
            
            $bill_location =$this->data['User']['bill_location'];
            $loc_type =$this->data['User']['loc_type'];
            
            if($role=='manager'){
                $pin =$this->data['User']['pin'] ?? 0;
            }else{
                $pin = 0;
            }
            if($loc_type==0){
                $location_ids =[];
            }else{
                $location_ids =$this->data['User']['location'];
            }
            
            $locationdetail = $this->Location->find('first', array(
                'conditions' => array('Location.id' => $bill_location)
            ));
                
            if (!empty($locationdetail)) {
                $locationnamee = $locationdetail['Location']['name'];
            }
            
            // print_r($settlement);exit;
            $this->User->query("UPDATE users SET name ='$name',mobile='$mobile',role='$role',pin='$pin',can_settlement='$settlement',location_id='$bill_location',location_name='$locationnamee',sync = 0,local_sync=0 WHERE id =". $id);
            if($password){
                $password = AuthComponent::password($password);
                $this->User->query("UPDATE users SET password ='$password',sync = 0,local_sync=0 WHERE id =". $id);
            }
            
            $this->User_location->query("UPDATE user_locations SET status=0,sync = 0,local_sync=0 WHERE user_id =". $id);
            
            foreach($location_ids as $location_id){
                $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
                $locationname=$locationdetail['Location']['name'];
                
                $isBill = (!empty($bill_location) && (
                    (is_array($bill_location) && in_array($location_id, $bill_location)) ||
                    (!is_array($bill_location) && $bill_location == $location_id)
               )) ? 1 : 0;
               
                $data['User_location']=array(
                    'user_id'=>$id,
                    'user_name'=>$username,
                    'location_id'=>$location_id,
                    'location_name'=>$locationname,
                    'billing_location'=>$isBill,
                    'sync' => 0,
                    'local_sync' => 0
                );
            
                if($this->User_location->saveAll($data['User_location']))
                {
                }else{
                    $this->Flash->error(__('The user Locations could not be saved. Please, try again.'));
                }
            }
            
            if (!empty($bill_location)) {
                $billLocations = is_array($bill_location) ? $bill_location : array($bill_location);
            
                foreach ($billLocations as $billLoc) {
                    if (!in_array($billLoc, $location_ids)) {
                        $locationdetail = $this->Location->find('first', array(
                            'conditions' => array('Location.id' => $billLoc)
                        ));
            
                        if (!empty($locationdetail)) {
                            $locationname = $locationdetail['Location']['name'];
            
                            $data['User_location'] = array(
                                'user_id'       => $id,
                                'user_name'     => $username,
                                'location_id'   => $billLoc,
                                'location_name' => $locationname,
                                'billing_location' => 1,
                                'sync' => 0,
                                'local_sync' => 0
                            );
            
                            $this->User_location->create();
                            if (!$this->User_location->save($data['User_location'])) {
                                $this->Flash->error(__('The extra bill Location could not be saved. Please, try again.'));
                            }
                        }
                    }
                }
            }
            
            $modules=moduleswithlabel;
            $checkedModules = [];
            $this->User->query("UPDATE user_modules SET status=0,sync = 0,local_sync=0 WHERE user_id =". $id);
            
            foreach ($modules as $moduleKey => $moduleLabel) {
                
                if (isset($this->data['User'][$moduleKey]) && $this->data['User'][$moduleKey]) {
                    $checkedModules[$moduleKey] = $this->data['User'][$moduleKey];
                    // print_r($moduleKey);
                     $data['User_module']=array(
                            'name'=>$moduleKey,
                            'user_id'=>$id,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        if($this->User_module->saveAll($data['User_module']))
                        {
                        }else{
                            $this->Flash->error(__('The user modules could not be saved. Please, try again.'));
                        }
                }
            }
            
            $this->Flash->success(__('User has been Updated.'));
            return $this->redirect(array('action' => 'cashier_list'));
        }else{
            $id=$_REQUEST['id'];
        
            $userdetail=$this->User->find('first',array('conditions'=>array('User.id'=>$id)));
            $this->set(compact('userdetail'));
            
            $locations=$this->Location->find('all',array('conditions'=>array('status'=>1)));
            $this->set(compact('locations'));
            
            // Get selected location IDs
            $selectedlocationss = $this->User_location->find('list', [
                'conditions' => ['User_location.status' => 1, 'User_location.user_id' => $id],
                'fields' => ['User_location.location_id', 'User_location.location_id']
            ]);
            
            $selectedLocationIds = array_keys($selectedlocationss);
            $hasMultiple = (count($selectedLocationIds) > 1) ? 1 : 0;
            
            // Get selected Billing location IDs
            $selectedbillinglocationss = $this->User_location->find('first', [
                'conditions' => ['User_location.status' => 1,'User_location.billing_location' => 1, 'User_location.user_id' => $id],
                'fields' => ['User_location.location_id', 'User_location.location_id']
            ]);
            
            $billing_location=$selectedbillinglocationss['User_location']['location_id'];
            
            $this->set(compact('selectedLocationIds','hasMultiple','billing_location'));
            
            $selectemodule="SELECT name FROM user_modules where user_id=$id and status=1"; 
            $selectemodules=$this->User_module->query($selectemodule);
            $this->set(compact('selectemodules'));
            
            $modules=moduleswithlabel;
            $this->set(compact('modules'));
        }
    }
    
    public function edit_subadmin()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        
        if ($this->data['User']['id']!='') {
          //  print_r($this->data['User']);exit;
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_subadmin?id='.$id));
            }
            
            $mobile = $this->data['User']['mobile'];
            $password = $this->data['User']['password'];
            $location_ids = $this->data['User']['location'];
            $role =$this->data['User']['role'];
            $userdetails=$this->User->find('first',array('conditions'=>array('User.id'=>$id)));
            $username=$userdetails['User']['username'];
            
            $this->User->query("UPDATE users SET name ='$name',mobile='$mobile',sync = 0,role='$role',local_sync=0 WHERE id =". $id);
            if($password){
                $password = AuthComponent::password($password);
                $this->User->query("UPDATE users SET password ='$password',sync = 0,local_sync=0 WHERE id =". $id);
            }
            
            $this->User_location->query("UPDATE user_locations SET status=0,sync = 0,local_sync=0 WHERE user_id =". $id);
            foreach($location_ids as $location_id){
                $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
                $locationname=$locationdetail['Location']['name'];
                
                $data['User_location']=array(
                    'user_id'=>$id,
                    'user_name'=>$username,
                    'location_id'=>$location_id,
                    'location_name'=>$locationname,
                    'sync' => 0,
                    'local_sync' => 0
                );
            
                if($this->User_location->saveAll($data['User_location']))
                {
                    $this->User->query("UPDATE users SET location_id ='$location_id',location_name='$locationname',sync = 0,local_sync=0 WHERE id =". $id);
                }else{
                    $this->Flash->error(__('The user Locations could not be saved. Please, try again.'));
                }
            }
            $modules=subadminmoduleswithlabel;
            $checkedModules = [];
            $this->User->query("UPDATE user_modules set status=0,sync = 0,local_sync=0 WHERE user_id =". $id);
        
            foreach ($modules as $moduleKey => $moduleLabel) {
                
                if (isset($this->data['User'][$moduleKey]) && $this->data['User'][$moduleKey]) {
                    $checkedModules[$moduleKey] = $this->data['User'][$moduleKey];
                    // print_r($moduleKey);
                     $data['User_module']=array(
                            'name'=>$moduleKey,
                            'user_id'=>$id,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        if($this->User_module->saveAll($data['User_module']))
                        {
                        }else{
                            $this->Flash->error(__('The user modules could not be saved. Please, try again.'));
                        }
                }
            }
            
            $this->Flash->success(__('Sub admin has been Updated.'));
            return $this->redirect(array('action' => 'subadmin_list'));
        }else{
            $id=$_REQUEST['id'];
        
            $userdetail=$this->User->find('first',array('conditions'=>array('User.id'=>$id)));
            $this->set(compact('userdetail'));
            
            $locations=$this->Location->find('all',array('conditions'=>array('status'=>1)));
            $this->set(compact('locations'));
            
            // Get selected location IDs
            $selectedlocationss = $this->User_location->find('list', [
                'conditions' => ['User_location.status' => 1, 'User_location.user_id' => $id],
                'fields' => ['User_location.location_id', 'User_location.location_id']
            ]);
            $selectedLocationIds = array_keys($selectedlocationss);
            $this->set(compact('selectedLocationIds'));
            
            $selectemodule="SELECT name FROM user_modules where user_id=$id and status=1"; 
            $selectemodules=$this->User_module->query($selectemodule);
            $this->set(compact('selectemodules'));
            
            $modules=subadminmoduleswithlabel;
            $this->set(compact('modules'));
        }
    }
    /*
    public function create_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_category'));
            }
            
            if(isset($_POST['subcat'])){
                $is_subcat=1;
            }else{
                $is_subcat=0;
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
            }
            
            $data['Catalog_category']=array(
                'name'=>$name,
                'is_subcategory'=>$is_subcat,
                'image'=>$filename,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Catalog_category->saveAll($data['Catalog_category']))
            {
                $lastInsertedID = $this->Catalog_category->id;
                if(isset($_POST['subcat'])){
                    $subcats = $_POST['subcat'];
                    foreach ($subcats as $subcat) {
                        $data['Catalog_subcategory']=array(
                            'cat_id'=>$lastInsertedID,
                            'name'=>$subcat,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Catalog_subcategory->saveAll($data['Catalog_subcategory']))
                        {
                            
                        }else{
                            $this->Flash->error(__('Sub category could not be saved. Please, try again.'));
                        }
                    }
                }
                
                
                $this->Flash->success(__('Category has been saved.'));
                return $this->redirect(array('action' => 'category_list'));
            } else {
                $this->Flash->error(__('Category could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories = $this->Catalog_category->query("SELECT * FROM catalog_category where id=$id");
        $this->set(compact('categories'));
        
        $subcategories=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$id and status=1");
        $this->set(compact('subcategories')); 
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_category?id='.$id));
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
                $this->Catalog_category->query("UPDATE `catalog_category` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
            }
            $this->Catalog_category->query("UPDATE `catalog_category` SET name='$name',sync = 0,local_sync=0 WHERE id=$id");
            
            $lastInsertedID = $id;
            if(isset($_POST['subcat'])){
                $subcats = $_POST['subcat'];
                foreach ($subcats as $subcat) {
                    $data['Catalog_subcategory']=array(
                        'cat_id'=>$lastInsertedID,
                        'name'=>$subcat,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Catalog_subcategory->saveAll($data['Catalog_subcategory']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sub category could not be saved. Please, try again.'));
                    }
                }
            }
            
            $subcategorychk=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$id and status=1");
            if($subcategorychk){
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$id");
            }else{
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='0',sync = 0,local_sync=0 WHERE id=$id");
            }
            
            $this->Flash->success(__('Category has been Updated.'));
            return $this->redirect(array('action' => 'category_list'));
        
        }
    }
    
    public function create_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            $subcategoriesname=$_POST['subcat'];
            $categoryid = $this->data['User']['category'];
            if($categoryid==''){
                $this->Flash->error(__('Select Category'));
                return $this->redirect(array('action' => 'create_subcategory'));
            }
            $filename='';
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
            }
            
            foreach($subcategoriesname as $subcategory){
                $data['Catalog_subcategory']=array(
                    'name'=>$subcategory,
                    'cat_id'=>$categoryid,
                    'image'=>$filename,
                    'sync' => 0,
                    'local_sync' => 0
                );
                
                if($this->Catalog_subcategory->saveAll($data['Catalog_subcategory']))
                {
                    $savechk=true;
                    
                }else{
                    $savechk=false;
                }
                
            }    
            
            if($savechk){
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$categoryid");
            
                $this->Flash->success(__('Sub Category has been saved.'));
                return $this->redirect(array('action' => 'subcategory_list'));
            } else {
                $this->Flash->error(__('Some sub Category could not be saved. Please, try again.'));
                return $this->redirect(array('action' => 'subcategory_list'));
            }
        }
        
        $categories=$this->Catalog_category->find('all',array('conditions'=>array('status'=>1)));
        $this->set(compact('categories'));
    
    }
    */
    public function create_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_category'));
            }
            
            if(isset($_POST['subcat'])){
                $is_subcat=1;
            }else{
                $is_subcat=0;
            }
            $food_type = $this->data['User']['food_type'];
            $filename='';
    
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }
            }
            
            $data['Catalog_category']=array(
                'name'=>$name,
                'food_type'=>$food_type,
                'is_subcategory'=>$is_subcat,
                'image'=>$filename,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Catalog_category->saveAll($data['Catalog_category']))
            {
                $lastInsertedID = $this->Catalog_category->id;
                if(isset($_POST['subcat'])){
                    $subcats = $_POST['subcat'];
                    $sub_food_types = $_POST['sub_food_type'];

                    foreach ($subcats as $key => $subcat) {

                        $data['Catalog_subcategory'] = array(
                            'cat_id' => $lastInsertedID,
                            'name' => $subcat,
                            'food_type' => $sub_food_types[$key],
                            'sync' => 0,
                            'local_sync' => 0
                        );

                        $this->Catalog_subcategory->create();

                        if(!$this->Catalog_subcategory->save($data['Catalog_subcategory'])){
                            $this->Flash->error(__('Sub category could not be saved.'));
                        }
                    }
                }
                
                $this->Flash->success(__('Category has been saved.'));
                return $this->redirect(array('action' => 'category_list'));
            } else {
                $this->Flash->error(__('Category could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories = $this->Catalog_category->query("SELECT * FROM catalog_category where id=$id");
        $this->set(compact('categories'));
        
        $subcategories=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$id and status=1");
        $this->set(compact('subcategories')); 
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_category?id='.$id));
            }

            $food_type = $this->data['User']['food_type'];
            $image=$this->data['User']['image'];
            $filename='';

            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }

                $this->Catalog_category->query("UPDATE `catalog_category` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
            }
            $this->Catalog_category->query("UPDATE `catalog_category` SET name='$name',food_type='$food_type',sync = 0,local_sync=0 WHERE id=$id");
            
            $lastInsertedID = $id;
            if(isset($_POST['subcat'])){
                $subcats = $_POST['subcat'];
                $sub_food_types = $_POST['sub_food_type'];

                foreach ($subcats as $key => $subcat) {

                    if(trim($subcat)==''){
                        continue;
                    }

                    $data['Catalog_subcategory'] = array(
                        'cat_id' => $id,
                        'name' => $subcat,
                        'food_type' => $sub_food_types[$key],
                        'sync' => 0,
                        'local_sync' => 0
                    );

                    $this->Catalog_subcategory->create();

                    if (!$this->Catalog_subcategory->save($data['Catalog_subcategory'])) {
                        $this->Flash->error(__('Sub category could not be saved.'));
                    }
                }
            }
            
            $subcategorychk=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$id and status=1");
            if($subcategorychk){
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$id");
            }else{
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='0',sync = 0,local_sync=0 WHERE id=$id");
            }
            
            $this->Flash->success(__('Category has been Updated.'));
            return $this->redirect(array('action' => 'category_list'));
        
        }
    }
    
    public function create_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            $subcategoriesname=$_POST['subcat'];
            $subFoodTypes = $_POST['sub_food_type'];
            $categoryid = $this->data['User']['category'];
            if($categoryid==''){
                $this->Flash->error(__('Select Category'));
                return $this->redirect(array('action' => 'create_subcategory'));
            }
            $filename='';
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
            }
            
            $savechk = true;

            foreach($subcategoriesname as $key => $subcategory){

                if(trim($subcategory) == ''){
                    continue;
                }

                $data['Catalog_subcategory'] = array(
                    'name' => $subcategory,
                    'cat_id' => $categoryid,
                    'food_type' => $subFoodTypes[$key],
                    'image' => $filename,
                    'sync' => 0,
                    'local_sync' => 0
                );

                $this->Catalog_subcategory->create();

                if(!$this->Catalog_subcategory->save($data['Catalog_subcategory'])){
                    $savechk = false;
                }
            }

            if($savechk){
                $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$categoryid");
            
                $this->Flash->success(__('Sub Category has been saved.'));
                return $this->redirect(array('action' => 'subcategory_list'));
            } else {
                $this->Flash->error(__('Some sub Category could not be saved. Please, try again.'));
                return $this->redirect(array('action' => 'subcategory_list'));
            }
        }
        
        $categories=$this->Catalog_category->find('all',array('conditions'=>array('status'=>1),
            'order' => array(
                'Catalog_category.name' => 'ASC'
            )));
        $this->set(compact('categories'));
    
    }

    public function create_tax()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_tax'));
            }
            $tax = $this->data['User']['tax'];
            if($tax==''){
                $this->Flash->error(__('Tax Percentage could not be Blank'));
                return $this->redirect(array('action' => 'create_tax'));
            }
            
            $data['Catalog_tax']=array(
                'name'=>$name,
                'percentage'=>$tax,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Catalog_tax->saveAll($data['Catalog_tax']))
            {
                $this->Flash->success(__('Tax has been saved.'));
                return $this->redirect(array('action' => 'tax_list'));
            } else {
                $this->Flash->error(__('Tax could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_tax()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $id=$_REQUEST['id'];
        $taxes=$this->Catalog_tax->find('all',array('conditions'=>array('id'=>$id)));
        $this->set(compact('taxes'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_tax'));
            }
            $tax = $this->data['User']['tax'];
            if($tax==''){
                $this->Flash->error(__('Tax Percentage could not be Blank'));
                return $this->redirect(array('action' => 'create_tax'));
            }
            
            $this->Catalog_tax->query("UPDATE `catalog_tax` SET name='$name',percentage='$tax',sync = 0,local_sync=0 WHERE id=$id");
            
            $this->Flash->success(__('Tax has been updated.'));
            return $this->redirect(array('action' => 'tax_list'));
        }
    }
    
    public function create_location()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $user_id=$this->Session->read('Auth.User.id');
        
        $this->layout = "users";
        
        $indiaStates=states;
        $this->set(compact('indiaStates'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_location'));
            }
            
            $username = $this->data['User']['username'];
            $userdetail=$this->Location->find('first',array('conditions'=>array('Location.username'=>$username)));
            if($userdetail){
                $this->Flash->error(__('Username already exist'));
                return $this->redirect(array('action' => 'create_location'));
            }
            $password = $this->data['User']['password'];
            $password = AuthComponent::password($password);
            $type = $this->data['User']['type'];
            $state = $this->data['User']['state'];
            $print_line1 = $this->data['User']['print_line1'];
            $print_line2 = $this->data['User']['print_line2'];
            $print_line3 = $this->data['User']['print_line3'];
            $print_line4 = $this->data['User']['print_line4'];
            $print_line5 = $this->data['User']['print_line5'];
            $print_line6 = $this->data['User']['print_line6'];
            $print_line7 = $this->data['User']['print_line7'];
            $print_line8 = $this->data['User']['print_line8'];
            $print_line9 = $this->data['User']['print_line9'];
            $print_line10 = $this->data['User']['print_line10'];
            $footer_msg = $this->data['User']['footer_msg'];
            $currency_symbol = $this->data['User']['currency_symbol'];
            
            $data['Location']=array(
                'name'=>$name,
                'username'=>$username,
                'password'=>$password,
                'type'=>$type,
                'state'=>$state,
                'print_line1'=>$print_line1,
                'print_line2'=>$print_line2,
                'print_line3'=>$print_line3,
                'print_line4'=>$print_line4,
                'print_line5'=>$print_line5,
                'print_line6'=>$print_line6,
                'print_line7'=>$print_line7,
                'print_line8'=>$print_line8,
                'print_line9'=>$print_line9,
                'print_line10'=>$print_line10,
                'footer_msg'=>$footer_msg,
                'currency_symbol'=>$currency_symbol,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Location->saveAll($data['Location']))
            {
                $lastInsertedID = $this->Location->id;
                
                if($type=='DC' && ($this->Session->read('Auth.User.role') == 'admin')){
                    $this->User->query("UPDATE users SET location_id ='$lastInsertedID',location_name='$name',sync = 0,local_sync=0 WHERE id =". $user_id);
                    $user = $this->Session->read('Auth.User');
                    $user['location_id'] = $lastInsertedID;
                    $this->Session->write('Auth.User', $user);
                }
                $this->Flash->success(__('Location has been saved.'));
                return $this->redirect(array('action' => 'location_list'));
            } else {
                $this->Flash->error(__('Location could not be saved. Please, try again.'));
            }
        }
    }
    
    public function create_coupon()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $code = $this->data['User']['code'];
            if($code==''){
                $this->Flash->error(__('Coupon Code could not be Blank'));
                return $this->redirect(array('action' => 'create_coupon'));
            }
            $coupon_value = $this->data['User']['coupon_value'];
            $month=$this->data['User']['expiry_date']['month'];
            $day=$this->data['User']['expiry_date']['day'];
            $year=$this->data['User']['expiry_date']['year'];
            
            $date=$year.'-'.$month.'-'.$day;

            $data['Coupon']=array(
                'code'=>$code,
                'value'=>$coupon_value,
                'expiry_date'=>$date,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Coupon->saveAll($data['Coupon']))
            {
                $this->Flash->success(__('Coupon has been saved.'));
                return $this->redirect(array('action' => 'coupon_list'));
            } else {
                $this->Flash->error(__('Coupon could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_coupon()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        
        if ($this->data['User']['id']!='') {
            $id=$this->data['User']['id'];
            $value = $this->data['User']['value'];
            if($value==''){
                $this->Flash->error(__('Coupon Value could not be Blank'));
                return $this->redirect(array('action' => 'edit_coupon?id='.$id));
            }
            
            $month=$this->data['User']['expiry']['month'];
            $day=$this->data['User']['expiry']['day'];
            $year=$this->data['User']['expiry']['year'];
            
            $date=$year.'-'.$month.'-'.$day;
            
            $this->Coupon->query("UPDATE coupons SET value ='$value',expiry_date='$date',sync = 0,local_sync=0 WHERE id =". $id);
            $this->Flash->success(__('Coupon has been Updated.'));
            return $this->redirect(array('action' => 'coupon_list'));
        }else{
            $id=$_REQUEST['id'];
        
            $coupons = $this->Coupon->query("SELECT * FROM coupons where id=$id");
            $this->set(compact('coupons'));
        }
        
    }
    
    public function create_table()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = ['status' => 1]; // always filter by active
        
        if ($userRole !== 'admin') {
            // normalize to array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $conditions['id IN'] = $userLocationIds;
        }
        
        $locations = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        
        $this->set(compact('locations'));
        if ($this->request->is(array('post', 'put'))) {
            
            $number = $this->data['User']['number'];
            if($number==''){
                $this->Flash->error(__('Table Number could not be Blank'));
                return $this->redirect(array('action' => 'create_table'));
            }
            $cover_charge = $this->data['User']['cover_charge'];
            $weekend_charge=$this->data['User']['weekend_charge'];
            $pax = $this->data['User']['pax'];
            $waiter = $this->data['User']['waiter'];
            $customer = $this->data['User']['customer'];
            
            $location_id =$this->data['User']['location'];
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
            $locationname=$locationdetail['Location']['name'];
            
            
            $tables=$this->Order_table->find('all',array('conditions'=>array('number'=>$number,'location_id'=>$location_id)));
            if(!empty($tables)){
                $this->Flash->error(__('Table already exist.'));
                return $this->redirect(array('action' => 'table_list'));
            }
            do {
                $pin = uniqid();
            } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
            
            
            $data['Order_table']=array(
                'number'=>$number,
                'reference_id'=>$pin,
                'cover_charge'=>$cover_charge,
                'weekend_charge'=>$weekend_charge,
                'pax'=>$pax,
                'is_waiter_required'=>$waiter,
                'is_customer_detail_required'=>$customer,
                'location_id'=>$location_id,
                'location_name'=>$locationname,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Order_table->saveAll($data['Order_table']))
            {
                $this->Flash->success(__('Table has been saved.'));
                return $this->redirect(array('action' => 'table_list'));
            } else {
                $this->Flash->error(__('Table could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_table()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        // $locationCondition = '';
        $conditions = ['status' => 1]; // always filter active locations

        if ($userRole !== 'admin') {
            // normalize to array for safety
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $conditions['id IN'] = $userLocationIds; // CakePHP will handle IN automatically
        }
        if ($this->data['User']['id']!='') {
          
            $id = $this->data['User']['id'];
            $cover_charge = $this->data['User']['cover_charge'];
            $pax = $this->data['User']['pax'];
            $weekend_charge = $this->data['User']['weekend_charge'];
            $waiter = $this->data['User']['waiter'];
            $customer = $this->data['User']['customer'];
            $location = $this->data['User']['location'];
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location)));
            $locationname=$locationdetail['Location']['name'];
            
            $this->Order_table->query("UPDATE order_tables SET cover_charge ='$cover_charge',pax='$pax',weekend_charge='$weekend_charge',is_waiter_required='$waiter',is_customer_detail_required='$customer',location_id='$location',location_name='$locationname',sync = 0,local_sync=0 WHERE id =". $id);
            $this->Flash->success(__('Table has been Updated.'));
            return $this->redirect(array('action' => 'table_list'));
        }else{
            $id=$_REQUEST['id'];
        
            $userdetail=$this->Order_table->find('first',array('conditions'=>array('Order_table.id'=>$id)));
            $this->set(compact('userdetail'));
            
            $locations=$this->Location->find('all',array('conditions'=>$conditions));
            $this->set(compact('locations'));
        }
    }
    
    public function tax_list() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Catalog_tax->query("SELECT * FROM catalog_tax where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function unit_list() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Catalog_unit->query("SELECT * FROM catalog_units where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_unit()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_unit'));
            }
            $unit=$this->Catalog_unit->find('all',array('conditions'=>array('name'=>$name)));
            if($unit){
                $this->Flash->error(__('Unit Name already exist'));
                return $this->redirect(array('action' => 'unit_list'));
            }
            $data['Catalog_unit']=array(
                'name'=>$name,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Catalog_unit->saveAll($data['Catalog_unit']))
            {
                $unit_id = $this->Catalog_unit->id;

                $data['Catalog_unit_mapping']=array(
                    'unit_id'=>$unit_id,
                    'unit_name'=>$name,
                    'mapped_unit_id'=>$unit_id,
                    'mapped_unit_name'=>$name,
                    'conversion_factor'=>1,
                    'sync' => 0,
                    'local_sync' => 0
                );
                if(!$this->Catalog_unit_mapping->saveAll($data['Catalog_unit_mapping']))
                {
                    $this->Flash->error(__('Unit could not be Mapped.'));
                }
                $this->Flash->success(__('Unit has been saved.'));
                return $this->redirect(array('action' => 'unit_list'));
            } else {
                $this->Flash->error(__('Unit could not be saved. Please, try again.'));
            }
        }
    }
    
    public function edit_unit()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $id=$_REQUEST['id'];
        $taxes=$this->Catalog_unit->find('all',array('conditions'=>array('id'=>$id)));
        $this->set(compact('taxes'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_unit'));
            }
            $this->Catalog_unit->query("UPDATE `catalog_units` SET name='$name',sync = 0,local_sync=0 WHERE id=$id");
            // Update unit_name where unit_id = $id
            $this->Catalog_unit_mapping->updateAll(
                [
                    'unit_name' => "'$name'",
                    'sync' => 0,
                    'local_sync' => 0
                ],
                ['Catalog_unit_mapping.unit_id' => $id]
            );
            
            // Update mapped_unit_name where mapped_unit_id = $id
            $this->Catalog_unit_mapping->updateAll(
                [
                    'mapped_unit_name' => "'$name'",
                    'sync' => 0,
                    'local_sync' => 0
                ],
                ['Catalog_unit_mapping.mapped_unit_id' => $id]
            );

            $this->Flash->success(__('Unit has been updated.'));
            return $this->redirect(array('action' => 'unit_list'));
        }
    }
    
    public function location_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        if($userRole == 'subadmin'){
            $id = $authUser['id'];                      
            $locations = $this->User_location->find('list', [
                'conditions' => ['status' => 1, 'user_id' => $id],
                'fields' => ['location_id']
            ]);
            $userLocationId = implode(',', array_values($locations));
        }
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $locationCondition = '';
        if ($userRole !== 'admin') {
            $locationCondition = "AND id IN (" . $userLocationId .")";
        }
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Location->query("SELECT * FROM locations where created between '$startDatetime' and  '$endDatetime' $locationCondition ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function coupon_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Coupon->query("SELECT * FROM coupons where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function table_list() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);     
        }
    
        $this->layout = "users";
    
        $users = [];
    
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
        
        $placeholders = implode(',', array_fill(0, count($userLocationIds), '?'));
        $conditions = "1=1";
        
        if ($userRole !== 'admin' && !empty($userLocationIds)) {
            $conditions .= " AND location_id IN ($placeholders)";
        }
        
        $users = $this->Order_table->query(
            "SELECT * FROM order_tables WHERE $conditions ORDER BY id DESC",
            $userLocationIds
        );
    
    
        $this->set(compact('users'));
    }

    public function booking_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-7 days'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Online_booking->query("SELECT * FROM online_bookings where created between '$startDatetime' and  '$endDatetime' and status=1 ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_product() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        // Load categories and subcategories into grouped select options
        $categorys = $this->Catalog_category->find('all', ['conditions' => ['status' => 1]]);
        $options = [];
    
        foreach ($categorys as $category) {
            $cat_id = $category['Catalog_category']['id'];
            $cat_name = $category['Catalog_category']['name'];
    
            $subcategorys = $this->Catalog_subcategory->find('all', [
                'conditions' => ['cat_id' => $cat_id, 'status' => 1]
            ]);
    
            if ($subcategorys) {
                $options[$cat_name] = [];
                foreach ($subcategorys as $sub) {
                    // $options[$cat_name][$sub['Catalog_subcategory']['id']] = $sub['Catalog_subcategory']['name'];
                    $sub_id = $sub['Catalog_subcategory']['id'];
                    $sub_name = $sub['Catalog_subcategory']['name'];
                    $options[$cat_name]["sub_$sub_id"] = $sub_name;
                }
            } else {
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        $locations=$this->Location->find('all',array('conditions'=>array('status'=>1)));
        $this->set(compact('locations'));
        
        $taxes = $this->Catalog_tax->find('all', array('conditions' => array('status' => 1)));
        
        $linkedGroupIds = $this->Inventory_linking->find('list', [
            'fields' => ['Inventory_linking.parent_id'],
            'conditions' => [
                'Inventory_linking.status' => 1,
                'Inventory_linking.parent_type' => 'Modifier_group',
                'Inventory_linking.component_type' => 'Modifier'
            ],
            'recursive' => -1
        ]);
        // print_r($linkedGroupIds);exit;
        $modifiers = $this->Catalog_modifier_group->find('all', [
            'conditions' => [
                'Catalog_modifier_group.status' => 1,
                'Catalog_modifier_group.id' => array_values($linkedGroupIds)
            ],
            'recursive' => -1
        ]);
        // $taxes = $this->Catalog_tax->find('all');
        $units = $this->Catalog_unit->find('all', ['conditions' => ['status' => 1]]);
        $kdss = $this->Pos_printer->find('all', ['conditions' => ['status' => 1]]);
        
        $this->set(compact('categorys', 'subcategorys', 'taxes', 'units', 'options', 'kdss','modifiers'));
    
        if ($this->request->is(['post', 'put'])) {
            $form = $this->request->data['Product'];
            // print_r($form);exit;
            if (empty($form['name'])) {
                $this->Flash->error(__('The product name cannot be blank.'));
                return $this->redirect(['action' => 'create_product']);
            }
        
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $form['category'] ?? '';
            
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Catalog_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Catalog_category']['name'];
                }
                
            } elseif (strpos($categoryInput, 'sub_') === 0) {
                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Catalog_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Catalog_subcategory']['name'];
                    $category_id = $subcatData['Catalog_subcategory']['cat_id'];
                    $category_name = $this->Catalog_category->field('name', ['id' => $category_id]);
                }
            } else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Catalog_category->create();
                if ($this->Catalog_category->save(['name' => $newcat,'sync'=>0,'local_sync'=>0])) {
                    $category_id = $this->Catalog_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
        
            //Unit
            $unit_id = null;
            $unit_name = '';
            
            $unitInput = $form['unit'] ?? '';
            
            if (is_numeric($unitInput)) {
                // Existing unit
                $unit_id = (int)$unitInput;
                $unitData = $this->Catalog_unit->findById($unit_id);
                $unit_name = $unitData['Catalog_unit']['name'] ?? '';
            } else {
                // New unit name
                $newunit = trim($unitInput);
                $this->Catalog_unit->create();
                if ($this->Catalog_unit->save(['name' => $newunit,
                            'sync' => 0,
                            'local_sync' => 0])) {
                    $unit_id = $this->Catalog_unit->id;
                    $unit_name = $newunit;
                } else {
                    $this->Flash->error(__('New unit could not be saved. Please try again.'));
                    return;
                }
            }
            
            
            $kds_id = null;
            $kds_name = '';
            $kds_input = $form['kds'] ?? '';
            $customKds = $_POST['custom_kds'] ?? [];
            
            if (is_numeric($kds_input)) {
                // Existing KDS selected
                $kds_id = (int)$kds_input;
                $existing = $this->Pos_printer->findById($kds_id);
                $kds_name = $existing['Pos_printer']['name'] ?? '';
            } elseif (!empty($customKds)) {
                // Custom KDS submitted via modal
                $firstKds = reset($customKds); // Get first added custom KDS
                
                $kdsData = [
                    'name' => $firstKds['name'] ?? '',
                    'ip' => $firstKds['ip'] ?? '',
                    'sync' => 0,
                    'local_sync' => 0
                ];

                $this->Pos_printer->create();
                if ($this->Pos_printer->save($kdsData)) {
                    $kds_id = $this->Pos_printer->id;
                    $kds_name = $kdsData['name'];
                    
                    $this->Pos_printer->updateAll(
                        [
                            'Pos_printer.kds'        => (int)$kds_id,
                            'Pos_printer.sync'       => 0,
                            'Pos_printer.local_sync' => 0
                        ],
                        [
                            'Pos_printer.id' => (int)$kds_id
                        ]
                    );

                } else {
                    $this->Flash->error(__('New KDS could not be saved.'));
                    return;
                }
            }
            
            // IMAGE
            $filename = '';
            if (!empty($form['image']['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'product_images' . DS;
                $filename = time() . '_' . preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $form['image']['name']);
                $uploadFile = $uploadPath . $filename;
                if (!move_uploaded_file($form['image']['tmp_name'], $uploadFile)) {
                    $filename = '';
                }
            }
            
            // PRODUCT MAIN DATA
            $data = [
                'Catalog_product' => [
                    'name' => $form['name'],
                    'cat_id' => $category_id,
                    'cat_name' => $category_name,
                    'subcat_id' => $subcategory_id,
                    'subcat_name' => $subcategory_name,
                    'unit' => $unit_id,
                    'unit_name' => $unit_name,
                    'description' => $form['description'] ?? '',
                    'dish_type' => $form['dish_type'] ?? 0,
                    'food_type' => $form['food_type'] ?? 0,
                    'package' => $form['package'] ?? 0,
                    'preparation_time' => $form['preparation'] ?? 0,
                    'serve_time' => $form['serve_time'] ?? 0,
                    'moq' => $form['moq'] ?? 0,
                    'sort_order' => $form['sort_order'] ?? 0,
                    'recommended' => $form['recommended'] ?? '',
                    'variation' => $form['variation'] ?? '',
                    'price' => $form['price'] ?? 0,
                    'markup_price' => $form['markup_price'] ?? 0,
                    'allergy_tags' => $form['allergy_tags'] ?? '',
                    'weight' => $form['weight'] ?? 0,
                    'serves_people' => $form['serves_people'] ?? 0,
                    'kds' => $kds_id,
                    'image' => $filename,
                    'is_discountable' => (!empty($form['is_discountable']) && $form['is_discountable'] != '0') ? 1 : 0,
                    'sync' => 0,
                    'local_sync' => 0
                ]
            ];
            
            if ($this->Catalog_product->save($data)) {
                $productId = $this->Catalog_product->id;
                
                // ✅ TAXES (dynamic + static)
                $finalTaxIds = [];
        
                if (!empty($form['custom_taxes'])) {
                    foreach ($form['custom_taxes'] as $customKey => $taxData) {
                        $name = trim($taxData['name'] ?? '');
                        $percentage = floatval($taxData['percentage'] ?? 0);
                        $isChecked = !empty($form['tax_ids'][$customKey]);
        
                        if ($name && $percentage && $isChecked) {
                            $existing = $this->Catalog_tax->find('first', ['conditions' => ['name' => $name, 'percentage' => $percentage]]);
                            $taxId = $existing['Catalog_tax']['id'] ?? null;
        
                            if (!$taxId) {
                                $this->Catalog_tax->create();
                                if ($this->Catalog_tax->save(['name' => $name, 'percentage' => $percentage,'sync' => 0,'local_sync' => 0])) {
                                    $taxId = $this->Catalog_tax->id;
                                }
                            }
        
                            if ($taxId) {
                                $finalTaxIds[$taxId] = ['name' => $name, 'percentage' => $percentage];
                            }
                        }
                    }
                }
                
                if (!empty($form['tax_ids'])) {
                    foreach ($form['tax_ids'] as $taxId => $selected) {
                        if (is_numeric($taxId) && $selected) {
                            $tax = $this->Catalog_tax->findById($taxId);
                            if ($tax) {
                                $finalTaxIds[$taxId] = [
                                    'name' => $tax['Catalog_tax']['name'],
                                    'percentage' => $tax['Catalog_tax']['percentage']
                                ];
                            }
                        }
                    }
                }
                
                if (!empty($finalTaxIds)) {
                    foreach ($finalTaxIds as $taxId => $tdata) {
                        $this->Catalog_product_tax->create();
                        $this->Catalog_product_tax->save([
                            'product_id' => $productId,
                            'product_name' => $form['name'],
                            'tax_id' => $taxId,
                            'tax_name' => $tdata['name'],
                            'tax_percentage' => $tdata['percentage'],
                            'sync' => 0,
                            'local_sync' => 0
                        ]);
                    }
                }
                
                //modifier group
                if (!empty($form['modifiers'])) {
                    foreach ($form['modifiers'] as $modifierId => $selected) {
                        if ($selected) {
                            $modifier_id = $this->Catalog_modifier_group->findById($modifierId);
                            if ($modifier_id) {
                                $finalModifierIds[$modifierId] = [
                                    'id' => $modifier_id['Catalog_modifier_group']['id'],
                                    'name' => $modifier_id['Catalog_modifier_group']['name']
                                ];
                            }
                        }
                    }
                }
                
                if (!empty($finalModifierIds)) {
                    foreach ($finalModifierIds as $modifierId => $tdata) {
                        $this->Inventory_linking->create();
                        $this->Inventory_linking->save([
                            'parent_type'=>'Product',
                            'parent_id'=>$productId,
                            'parent_name'=>$form['name'],
                            'component_type'=>'Modifier_group',
                            'component_id'=>$modifierId,
                            'component_name'=>$tdata['name'],
                            'quantity'=>1,
                            'sync' => 0,
                            'local_sync' => 0
                        ]);
                    }
                }
                
                // ✅ ATTRIBUTES
                if (!empty($_POST['custom_attributes'])) {
                    foreach ($_POST['custom_attributes'] as $attr) {
                        $attrName = trim($attr['name'] ?? '');
                        $attrValue = trim($attr['value'] ?? '');
                        if ($attrName && $attrValue) {
                            $this->Catalog_product_attribute->create();
                            $this->Catalog_product_attribute->saveAll([
                                'product_id' => $productId,
                                'name' => $attrName,
                                'value' => $attrValue,
                                'sync' => 0,
                                'local_sync' => 0
                            ]);
                        }
                    }
                }
                
                $this->Flash->success(__('Product has been saved successfully.'));
                return $this->redirect(['action' => 'product_list']);
            } else {
                $this->Flash->error(__('Product could not be saved. Please try again.'));
            }
        }

    }
    /*
    public function product_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Catalog_product->query("SELECT * FROM catalog_product where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    */
  /*  public function product_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Catalog_product->query("SELECT catalog_product.*, COALESCE(vpc.recipe_cost, 0) as recipe_cost FROM catalog_product LEFT JOIN v_product_recipe_cost vpc ON vpc.id = catalog_product.id WHERE catalog_product.created BETWEEN '$startDatetime' AND '$endDatetime' ORDER BY catalog_product.id DESC");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    */
	
	public function product_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Catalog_product->query(
            "SELECT catalog_product.*, COALESCE(vpc.recipe_cost, 0) as recipe_cost
             FROM catalog_product
             LEFT JOIN v_product_recipe_cost vpc ON vpc.id = catalog_product.id
             WHERE catalog_product.created BETWEEN '$startDatetime' AND '$endDatetime'
             ORDER BY catalog_product.id DESC"
        );
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
	
    public function view_product()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = 'users';
    
        $id = $_REQUEST['id'] ?? null;
        if (empty($id)) {
            $this->Flash->error('Invalid product ID.');
            return $this->redirect(['action' => 'product_list']);
        }
    
        // Get product with related fields
        $product = $this->Catalog_product->find('first', [
            'conditions' => ['Catalog_product.id' => $id],
            'joins' => [
                [
                    'table' => 'pos_printers',
                    'alias' => 'Kds',
                    'type' => 'LEFT',
                    'conditions' => ['Kds.kds = Catalog_product.kds']
                ]
            ],
            'fields' => [
                'Catalog_product.*',
                'Kds.name as kds_name'
            ]
        ]);
        if (empty($product)) {
            $this->Flash->error('Product not found.');
            return $this->redirect(['action' => 'product_list']);
        }
        
        $product = array_merge($product['Catalog_product'], [
            'kds_name'    => $product['Kds']['kds_name'] ?? ''
        ]);
        // Get selected tax IDs for the product
        $productTaxData = $this->Catalog_product_tax->find('list', [
            'fields' => ['Catalog_product_tax.id', 'Catalog_product_tax.tax_id'],
            'conditions' => ['Catalog_product_tax.product_id' => $id,'Catalog_product_tax.status' => 1]
        ]);
        $selectedTaxIds = array_values($productTaxData);
    
        // Get all tax options (with name and percentage)
        $taxes = $this->Catalog_product_tax->query("
            SELECT cpt.tax_id, CONCAT(ct.name, '(', ct.percentage, '%)') as taxname
            FROM catalog_product_tax cpt
            JOIN catalog_tax ct ON ct.id = cpt.tax_id
            WHERE cpt.product_id = $id and cpt.status=1
        ");
        
        $modifiers = $this->Inventory_linking->query("
            SELECT *
            FROM inventory_linking
            WHERE parent_id = $id and parent_type='Product' and component_type='Modifier_group' and status=1
        ");
        
        $attributes = $this->Catalog_product_attribute->query("
            SELECT name,value
            FROM catalog_product_attribute 
            WHERE catalog_product_attribute.product_id = $id and catalog_product_attribute.status=1
        ");
        
        // Send to view
        $this->set(compact('product', 'taxes', 'selectedTaxIds','attributes','modifiers'));
    }

    public function view_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories = $this->Catalog_category->query("SELECT * FROM catalog_category where id=$id and status=1");
        $this->set(compact('categories'));
        
        $subcategories=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$id and status=1");
        $this->set(compact('subcategories')); 
    }
    
    public function view_location()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $locations = $this->Location->query("SELECT * FROM locations where id=$id and status=1");
        $this->set(compact('locations'));
        
    }
    
    public function edit_location()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $indiaStates=states;
        $this->set(compact('indiaStates'));
        
        $user_id=$this->Session->read('Auth.User.id');
        if ($this->data['User']['id']!='') {
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_location?id='.$id));
            }
            $username = $this->data['User']['username'];
            $password = $this->data['User']['password'];
            $type = $this->data['User']['type'];
            $state = $this->data['User']['state'];
            $print_line1 = $this->data['User']['print_line1'];
            $print_line2 = $this->data['User']['print_line2'];
            $print_line3 = $this->data['User']['print_line3'];
            $print_line4 = $this->data['User']['print_line4'];
            $print_line5 = $this->data['User']['print_line5'];
            $print_line6 = $this->data['User']['print_line6'];
            $print_line7 = $this->data['User']['print_line7'];
            $print_line8 = $this->data['User']['print_line8'];
            $print_line9 = $this->data['User']['print_line9'];
            $print_line10 = $this->data['User']['print_line10'];
            $footer_msg = $this->data['User']['footer_msg'];
            $currency_symbol = $this->data['User']['currency_symbol'];
            
            if($password!=''){
                $password = AuthComponent::password($password);
                $this->Location->query("UPDATE locations SET password='$password',sync = 0,local_sync=0 WHERE id =". $id);
            }
            $this->Location->query("UPDATE locations SET username ='$username',type='$type',name ='$name',state='$state',print_line1='$print_line1',print_line2='$print_line2',print_line3='$print_line3',print_line4='$print_line4',print_line5='$print_line5',print_line6='$print_line6',print_line7='$print_line7',print_line8='$print_line8',print_line9='$print_line9',print_line10='$print_line10',footer_msg='$footer_msg',currency_symbol='$currency_symbol',sync = 0,local_sync=0 WHERE id =". $id);
            
            $this->Kds_user->query("UPDATE kds_users SET location_name ='$name',sync = 0,local_sync=0 WHERE location_id =". $id);
            $this->Kds_users_station_mapping->query("UPDATE kds_users_station_mapping SET station_store_name ='$name',sync = 0,local_sync=0 WHERE station_store_id =". $id);
            $this->Pos_printer->query("UPDATE pos_printers SET store_name ='$name',sync = 0,local_sync=0 WHERE store_id =". $id);
            $this->User_location->query("UPDATE user_locations SET location_name ='$name',sync = 0,local_sync=0 WHERE status=1 and location_id =". $id);
            $this->Inventory_vendor_service_area->query("UPDATE inventory_vendor_service_areas SET area_name ='$name',sync = 0,local_sync=0 WHERE is_deleted=0 and area_id =". $id);
            $this->Catalog_category_branches->query("UPDATE catalog_category_branches SET location_name ='$name',sync = 0,local_sync=0 WHERE location_id =". $id);
            $this->Catalog_product_branches->query("UPDATE catalog_product_branches SET location_name ='$name',sync = 0,local_sync=0 WHERE location_id =". $id);
            $this->Order_table->query("UPDATE order_tables SET location_name ='$name',sync = 0,local_sync=0 WHERE location_id =". $id);
            $this->Order_waiter->query("UPDATE order_waiters SET location_name ='$name',sync = 0,local_sync=0 WHERE location_id =". $id);
            
            if($type=='DC' && ($this->Session->read('Auth.User.role') == 'admin')){
                $this->User->query("UPDATE users SET location_id ='$id',location_name='$name',sync = 0,local_sync=0 WHERE id =". $user_id);
                $user = $this->Session->read('Auth.User');
                $user['location_id'] = $id;
                $this->Session->write('Auth.User', $user);
            }
            $this->Flash->success(__('Location has been Updated.'));
            return $this->redirect(array('action' => 'location_list'));
        }else{
            $id=$_REQUEST['id'];
        
            $locations = $this->Location->query("SELECT * FROM locations where id=$id and status=1");
            $this->set(compact('locations'));
        }
        
    }
    
    public function edit_product()
    {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(array('controller' => 'dashboard', 'action' => 'login'));
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        // Fetch the selected product's details
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product WHERE id = $id and status=1");
        $categories = $this->Catalog_category->find('all', array('conditions' => array('status' => 1), 'order' => array('name' => 'asc')));
    
        $options = [];
        if (!empty($products[0]['catalog_product']['subcat_id'])) {
            $selectedcatId = $products[0]['catalog_product']['subcat_id'];
            $selectedType = 'sub';
        } else {
            $selectedcatId = $products[0]['catalog_product']['cat_id'];
            $selectedType = 'cat';
        }
        
        foreach ($categories as $category) {
            $cat_id = $category['Catalog_category']['id'];
            $cat_name = $category['Catalog_category']['name'];
    
            $subcategories = $this->Catalog_subcategory->find('all', array(
                'conditions' => array('cat_id' => $cat_id, 'status' => 1),
                'order' => array('name' => 'asc')
            ));
    
            if (!empty($subcategories)) {
                $options[$cat_name] = [];
                foreach ($subcategories as $subcategory) {
                    $subcat_id = $subcategory['Catalog_subcategory']['id'];
                    $subcat_name = $subcategory['Catalog_subcategory']['name'];
                    if ($subcat_id == $selectedcatId  && $selectedType == 'sub') {
                        $selectedcategory = $subcategory['Catalog_subcategory'];
                        $selectedcategory['_type'] = 'sub';
                    }
                    $options[$cat_name]["sub_$subcat_id"] = $subcat_name;
                    
                }
            } else {
                if ($cat_id == $selectedcatId  && $selectedType == 'cat') {
                    $selectedcategory = $category['Catalog_category'];
                    $selectedcategory['_type'] = 'cat';
                }
                $options["cat_$cat_id"] = $cat_name;
            }
        }
    
        if (!empty($selectedcategory)) {
            $key_prefix = ($selectedcategory['_type'] == 'sub') ? 'sub_' : 'cat_';
            $options = array($key_prefix . $selectedcategory['id'] => $selectedcategory['name']) + $options;
        }
    
        $taxes = $this->Catalog_tax->find('all', array('conditions' => array('status' => 1)));
        $units = $this->Catalog_unit->find('all', array('conditions' => array('status' => 1)));
        $kdss = $this->Pos_printer->find('all', array('conditions' => array('status' => 1)));
        $locations=$this->Location->find('all',array('conditions'=>array('status'=>1)));
        $this->set(compact('locations'));
        
        $this->set(compact('categories', 'subcategories', 'taxes', 'units', 'options', 'selectedcatId', 'kdss'));
        $this->set(compact('products'));
    
        $product_taxes = $this->Catalog_product_tax->find('all', array('conditions' => array('product_id' => $id,'status' => 1), 'order' => array('id' => 'desc')));
        $this->set(compact('product_taxes'));
    
        $attributes = $this->Catalog_product_attribute->find('all', [
            'conditions' => ['product_id' => $id,'status' => 1],
            'order' => ['id' => 'desc']
        ]);
        
        $customAttributes = array_map(function($attr) {
            return [
                'name' => $attr['Catalog_product_attribute']['name'],
                'value' => $attr['Catalog_product_attribute']['value']
            ];
        }, $attributes);
        $this->set(compact('customAttributes'));

        
        if (!empty($this->data['User']['id'])) {
            $form = $this->data['User'];
            $id = $form['id'];
            $name = trim($form['name']);
    
            if ($name == '') {
                $this->Flash->error(__('The Name could not be blank.'));
                return $this->redirect(['action' => 'edit_product', '?' => ['id' => $id]]);
            }
            
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $form['category'] ?? '';
            
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Catalog_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Catalog_category']['name'];
                }
            }elseif (strpos($categoryInput, 'sub_') === 0) {
                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Catalog_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Catalog_subcategory']['name'];
                    $category_id = $subcatData['Catalog_subcategory']['cat_id'];
                    $category_name = $this->Catalog_category->field('name', ['id' => $category_id]);
                }
            }else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Catalog_category->create();
                if ($this->Catalog_category->save(['name' => $newcat,'sync' => 0,'local_sync' => 0])) {
                    $category_id = $this->Catalog_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
            
            // UNIT
            $unit_id = null;
            $unit_name = '';
            
            $unitInput = $form['unit'] ?? '';
            
            if (is_numeric($unitInput)) {
                $unit_id = (int)$unitInput;
                $unitData = $this->Catalog_unit->findById($unit_id);
                $unit_name = $unitData['Catalog_unit']['name'] ?? '';
            } else {
                $newunit = trim($unitInput);
                $this->Catalog_unit->create();
                if ($this->Catalog_unit->save(['name' => $newunit,'sync' => 0,'local_sync' => 0])) {
                    $unit_id = $this->Catalog_unit->id;
                    $unit_name = $newunit;
                } else {
                    $this->Flash->error(__('New unit could not be saved.'));
                    return;
                }
            }
            
            // KDS
            $kds_id = null;
            $kds_name = '';
            $kds_input = $form['kds'] ?? '';
            $customKds = $_POST['custom_kds'] ?? [];
            
            if (is_numeric($kds_input)) {
                $kds_id = (int)$kds_input;
                $existing = $this->Pos_printer->findById($kds_id);
                $kds_name = $existing['Pos_printer']['name'] ?? '';
            } elseif (!empty($customKds)) {
                $firstKds = reset($customKds);
                $locationdetail = $this->Location->findById($firstKds['location']);
                $locationname = $locationdetail['Location']['name'] ?? '';
            
                $kdsData = [
                    'name' => $firstKds['name'],
                    'ip' => $firstKds['ip'],
                    'sync' => 0,
                    'local_sync' => 0
                ];
            
                $this->Pos_printer->create();
                if ($this->Pos_printer->save($kdsData)) {
                    $kds_id = $this->Pos_printer->id;
                    $kds_name = $kdsData['name'];
                    
                    $this->Pos_printer->updateAll(
                        [
                            'Pos_printer.kds'        => (int)$kds_id,
                            'Pos_printer.sync'       => 0,
                            'Pos_printer.local_sync' => 0
                        ],
                        [
                            'Pos_printer.id' => (int)$kds_id
                        ]
                    );

                } else {
                    $this->Flash->error(__('New KDS could not be saved.'));
                    return;
                }
            }
            
            // IMAGE
            $filename = '';
            if (!empty($form['image']['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'product_images' . DS;
                $filename = time() . '_' . preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $form['image']['name']);
                $uploadFile = $uploadPath . $filename;
                if (!move_uploaded_file($form['image']['tmp_name'], $uploadFile)) {
                    $filename = '';
                }
            }
            
            $productData = [
                'id' => $id,
                'name' => $name,
                'description' => $form['description'],
                'dish_type' => $form['dish_type'],
                'food_type' => $form['food_type'],
                'package' => $form['package'],
                'sort_order' => $form['sort_order'],
                'recommended' => $form['recommended'],
                'variation' => $form['variation'],
                'price' => $form['price'],
                'preparation_time' => $form['preparation'] ?? 0,
                'serve_time' => $form['serve_time'] ?? 0,
                'moq' => $form['moq'] ?? 0,
                'allergy_tags' => $form['allergy_tags'],
                'weight' => $form['weight'],
                'serves_people' => $form['serves_people'],
                'unit' => $unit_id,
                'unit_name' => $unit_name,
                'cat_id' => $category_id,
                'cat_name' => $category_name,
                'subcat_id' => $subcategory_id,
                'subcat_name' => $subcategory_name,
                'kds' => $kds_id,
                'is_discountable' => (!empty($form['is_discountable']) && $form['is_discountable'] != '0') ? 1 : 0,
                'sync' => 0,
                'local_sync' => 0
            ];

            if ($filename != '') {
                $productData['image'] = $filename;
            }
            
            $this->Catalog_product->save($productData);
            
            $package = $form['package'];
            if ($package == 0) {
                // Deactivate all package mappings for this product
                $this->Catalog_package->updateAll(
                    ['status' => 0,'sync' => 0,'local_sync' => 0],
                    ['main_product_id' => $id]
                );
            }
            
            // ✅ TAXES (dynamic + static)
            
            $this->Catalog_product_tax->query("update catalog_product_tax set status=0,sync = 0,local_sync=0 WHERE product_id =" . $id);
            $finalTaxIds = [];
            if (!empty($_POST['User']['custom_taxes'])) {
                foreach ($_POST['User']['custom_taxes'] as $customKey => $taxData) {
                    $name = trim($taxData['name'] ?? '');
                    $percentage = floatval($taxData['percentage'] ?? 0);
                    $isChecked = !empty($_POST['User']['tax_ids'][$customKey]);
                    
                    if ($name && $percentage && $isChecked) {
                        $existing = $this->Catalog_tax->find('first', ['conditions' => ['name' => $name, 'percentage' => $percentage]]);
                        $taxId = $existing['Catalog_tax']['id'] ?? null;
                        
                        if (!$taxId) {
                            $this->Catalog_tax->create();
                            if ($this->Catalog_tax->save(['name' => $name, 'percentage' => $percentage,'sync' => 0,'local_sync' => 0])) {
                                $taxId = $this->Catalog_tax->id;
                            }
                        }
    
                        if ($taxId) {
                            $finalTaxIds[$taxId] = ['name' => $name, 'percentage' => $percentage];
                        }
                    }
                }
            }
                    
            if (!empty($_POST['data']['tax_ids'])) {
                foreach ($_POST['data']['tax_ids'] as $taxId => $selected) {
                    if (is_numeric($taxId) && $selected) {
                        $tax = $this->Catalog_tax->findById($taxId);
                        if ($tax) {
                            $finalTaxIds[$taxId] = [
                                'name' => $tax['Catalog_tax']['name'],
                                'percentage' => $tax['Catalog_tax']['percentage']
                            ];
                        }
                    }
                }
            }
            foreach ($finalTaxIds as $taxId => $tdata) {
                $this->Catalog_product_tax->create();
                $this->Catalog_product_tax->save([
                    'product_id' => $id,
                    'product_name' => $form['name'],
                    'tax_id' => $taxId,
                    'tax_name' => $tdata['name'],
                    'tax_percentage' => $tdata['percentage'],
                    'sync' => 0,
                    'local_sync' => 0
                ]);
            }
            
            // ✅ ATTRIBUTES
            
            $this->Catalog_product_attribute->query("UPDATE catalog_product_attribute SET status=0,sync = 0,local_sync=0 WHERE product_id =" . $id);
            
            if (!empty($_POST['custom_attributes'])) {
                foreach ($_POST['custom_attributes'] as $attr) {
                    $attrName = trim($attr['name'] ?? '');
                    $attrValue = trim($attr['value'] ?? '');
                    if ($attrName && $attrValue) {
                        $this->Catalog_product_attribute->create();
                        $this->Catalog_product_attribute->saveAll([
                            'product_id' => $id,
                            'name' => $attrName,
                            'value' => $attrValue,
                            'sync' => 0,
                            'local_sync' => 0
                        ]);
                    }
                }
            }
            
            $this->Flash->success(__('Product has been Updated.'));
            return $this->redirect(array('action' => 'product_list'));
        }
    }
    /*
    public function view_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories=$this->Catalog_subcategory->query("SELECT *,(SELECT name FROM `catalog_category` WHERE id=catalog_subcategory.cat_id) as catname FROM catalog_subcategory where id=$id");
        $this->set(compact('categories')); 
    }
    
    public function edit_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $subcategories=$this->Catalog_subcategory->query("SELECT *,(SELECT name FROM `catalog_category` WHERE id=catalog_subcategory.cat_id) as catname FROM catalog_subcategory where id=$id");
        $this->set(compact('subcategories')); 
        
        $categories=$this->Catalog_category->find('all',array('conditions'=>array('status'=>1),'order' => array(
                'name' => 'asc' // Order by the 'created' field in ascending order
            )));
        $this->set(compact('categories'));
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_subcategory?id='.$id));
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
                $this->Catalog_subcategory->query("UPDATE `catalog_subcategory` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
            }
            $category=$this->data['User']['category'];
        
            $categoryid = $this->Catalog_subcategory->query("SELECT cat_id FROM catalog_subcategory where id=$id");
            $cat_id=$categoryid['0']['catalog_subcategory']['cat_id'];
        
            $this->Catalog_subcategory->query("UPDATE `catalog_subcategory` SET name='$name',cat_id=$category,sync = 0,local_sync=0 WHERE id=$id");
            $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$category");
            
            $subcategorychk=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$cat_id and status=1");
            if($subcategorychk){
                $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$cat_id");
            }else{
                $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=0,sync = 0,local_sync=0 WHERE id=$cat_id");
            }
            
            $this->Flash->success(__('Sub Category has been Updated.'));
            return $this->redirect(array('action' => 'subcategory_list'));
        
        }
    
    }
    */
    
    public function view_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories=$this->Catalog_subcategory->query("SELECT *,(SELECT name FROM `catalog_category` WHERE id=catalog_subcategory.cat_id) as catname FROM catalog_subcategory where id=$id");
        $this->set(compact('categories')); 
    }
    
    public function edit_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $subcategories=$this->Catalog_subcategory->query("SELECT *,(SELECT name FROM `catalog_category` WHERE id=catalog_subcategory.cat_id) as catname FROM catalog_subcategory where id=$id");
        $this->set(compact('subcategories')); 
        
        $categories=$this->Catalog_category->find('all',array('conditions'=>array('status'=>1),'order' => array(
                'name' => 'asc' // Order by the 'created' field in ascending order
            )));
        $this->set(compact('categories'));
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_subcategory?id='.$id));
            }
            $filename='';

            $food_type = $this->data['User']['food_type'];
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                    $this->Catalog_subcategory->query("UPDATE `catalog_subcategory` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
                }
            }
            $category=$this->data['User']['category'];
        
            $categoryid = $this->Catalog_subcategory->query("SELECT cat_id FROM catalog_subcategory where id=$id");
            $cat_id=$categoryid['0']['catalog_subcategory']['cat_id'];
        
            $this->Catalog_subcategory->query("UPDATE `catalog_subcategory` SET name='$name',cat_id=$category,food_type='$food_type',sync = 0,local_sync=0 WHERE id=$id");
            $this->Catalog_category->query("UPDATE `catalog_category` SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$category");
            
            $subcategorychk=$this->Catalog_subcategory->query("SELECT * FROM catalog_subcategory where cat_id=$cat_id and status=1");
            if($subcategorychk){
                $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$cat_id");
            }else{
                $this->Catalog_category->query("UPDATE catalog_category SET is_subcategory=0,sync = 0,local_sync=0 WHERE id=$cat_id");
            }
            
            $this->Flash->success(__('Sub Category has been Updated.'));
            return $this->redirect(array('action' => 'subcategory_list'));
        
        }
    
    }

    public function create_sku()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $units=$this->Catalog_unit->find('all',array('conditions'=>array('status'=>1)));
        
        $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
        
        $categorys = $this->Inventory_category->find('all', ['conditions' => ['status' => 1]]);
        
        $options = [];
        foreach ($categorys as $category) {
            $cat_id = $category['Inventory_category']['id'];
            $cat_name = $category['Inventory_category']['name'];
        
            $subcategorys = $this->Inventory_subcategory->find('all', [
                'conditions' => ['cat_id' => $cat_id, 'status' => 1]
            ]);
        
            if (!empty($subcategorys)) {
                foreach ($subcategorys as $sub) {
                    $sub_id = $sub['Inventory_subcategory']['id'];
                    $sub_name = $sub['Inventory_subcategory']['name'];
                    $options[$cat_name]["sub_$sub_id"] = $sub_name;
                }
            } else {
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        $this->set(compact('categorys', 'subcategorys', 'units', 'taxes', 'options'));

        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_sku'));
            }
            
            $name = $this->data['User']['name'];
            $brand = $this->data['User']['brand'];
            $unit = $this->data['User']['unit'];
            $item_type = $this->data['User']['item_type'];
            $price = $this->data['User']['price'];
            $remarks = $this->data['User']['remarks'];
            $conunit = $this->data['User']['conunit'];
            $factor = $this->data['User']['factor'];
            $conprice = $this->data['User']['conprice'];
            
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $this->data['User']['category'] ?? '';
            
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Inventory_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Inventory_category']['name'];
                }
                
            } elseif (strpos($categoryInput, 'sub_') === 0) {

                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Inventory_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Inventory_subcategory']['name'];
                    $category_id = $subcatData['Inventory_subcategory']['cat_id'];
                    $category_name = $this->Inventory_category->field('name', ['id' => $category_id]);
                }
            } else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Inventory_category->create();
                if ($this->Inventory_category->save(['name' => $newcat,
                    'sync' => 0,
                    'local_sync' => 0])) {
                    $category_id = $this->Inventory_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
            
            $unitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$unit)));
            $conunitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$conunit)));
            
            $data['Inventory_sku']=array(
                'name'=>$name,
                'brand'=>$brand,
                'cat_id' => $category_id,
                'cat_name' => $category_name,
                'subcat_id' => $subcategory_id,
                'subcat_name' => $subcategory_name,
                'unit'=>$unit,
                'item_type' => $item_type,
                'unit_name'=>$unitname['Catalog_unit']['name'],
                'consumption_unit_id'=>$conunit,
                'consumption_unit_name'=>$conunitname['Catalog_unit']['name'],
                'consumption_factor'=>$factor,
                'consumption_unit_price'=>$conprice,
                'price'=>$price,
                'remarks'=>$remarks,
                'moq' => $this->data['User']['moq'] ?? 0,
                'stock' => $this->data['User']['stock'] ?? 0,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Inventory_sku->saveAll($data['Inventory_sku']))
            {
                $lastInsertedID = $this->Inventory_sku->id;
                
                $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
                foreach ($taxes as $taxess) {
                    $taxID = $taxess['Inventory_tax']['id'];
                    if (!empty($this->request->data['User']['tax_' . $taxID])) {
                        $selectedTaxes[] = $this->request->data['User']['tax_' . $taxID];
                        $taxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('id'=>$taxID)));
                        if($taxdetail){
                            $data['Inventory_sku_tax']=array(
                                'product_id'=>$lastInsertedID,
                                'product_name'=>$name,
                                'tax_id'=>$taxID,
                                'tax_name'=>$taxdetail['Inventory_tax']['name'],
                                'tax_percentage'=>$taxdetail['Inventory_tax']['percentage'],
                                'sync' => 0,
                                'local_sync' => 0
                            );
                            
                            if($this->Inventory_sku_tax->saveAll($data['Inventory_sku_tax']))
                            {
                                
                            }else{
                                $this->Flash->error(__('SKU tax could not be saved. Please, try again.'));
                            }
                        }
                    }
                }
                
                if(isset($_POST['custom_tax_name'])){
                
                    $taxnames=$_POST['custom_tax_name'];
                    $taxvalues=$_POST['custom_tax_value'];
                       
                    for ($i = 0; $i < count($taxnames); $i++) {
                        $taxname = $taxnames[$i];
                        $percentage = $taxvalues[$i];
                        
                        $newtaxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('name'=>$taxname,'percentage'=>$percentage)));
                        if(empty($newtaxdetail)){
                            $data['Inventory_tax']=array(
                                'name'=>$taxname,
                                'percentage'=>$percentage,
                                'sync' => 0,
                                'local_sync' => 0
                            );
                            
                            if($this->Inventory_tax->saveAll($data['Inventory_tax']))
                            {
                                $taxlastInsertedID = $this->Inventory_tax->id;
                        
                            } else {
                                $this->Flash->error(__('New Tax could not be saved. Please, try again.'));
                            }
                        }
                        
                        $data['Inventory_sku_tax']=array(
                            'product_id'=>$lastInsertedID,
                            'product_name'=>$name,
                            'tax_id'=>$taxlastInsertedID,
                            'tax_name'=>$taxname,
                            'tax_percentage'=>$percentage,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_sku_tax->saveAll($data['Inventory_sku_tax']))
                        {
                            
                        }else{
                            $this->Flash->error(__('Sku New tax could not be saved. Please, try again.'));
                        }
                        
                    }
                }
                $this->Flash->success(__('Sku has been saved.'));
                return $this->redirect(array('action' => 'sku_list'));
            } else {
                $this->Flash->error(__('Sku could not be saved. Please, try again.'));
            }
        }
        
    }
    
    public function sku_list()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Inventory_sku->query("SELECT * FROM inventory_skus where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function edit_sku()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $id=$_REQUEST['id'];
    
        $products = $this->Inventory_sku->query("SELECT * FROM inventory_skus where id=$id");
        $this->set(compact('products'));
        
        $product_taxes=$this->Inventory_sku_tax->find('all',array('conditions'=>array('product_id'=>$id,'status' => 1),'order'=>array('id'=>'desc')));
        $this->set(compact('product_taxes'));
        
        $categories = $this->Inventory_category->find('all', array('conditions' => array('status' => 1), 'order' => array('name' => 'asc')));
        
        $units=$this->Catalog_unit->find('all',array('conditions'=>array('status'=>1)));
        
        $unit=$products[0]['inventory_skus']['unit'];
        $conunits=$this->Catalog_unit_mapping->find('all',array('conditions'=>array('status'=>1,'unit_id'=>$unit)));
        
        $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
        $options = [];
        if (!empty($products[0]['inventory_skus']['subcat_id'])) {
            $selectedcatId = $products[0]['inventory_skus']['subcat_id'];
            $selectedType = 'sub';
        } else {
            $selectedcatId = $products[0]['inventory_skus']['cat_id'];
            $selectedType = 'cat';
        }
        
        $selectedcategory = null;
        foreach ($categories as $category) {
            $cat_id = $category['Inventory_category']['id'];
            $cat_name = $category['Inventory_category']['name'];
    
            $subcategories = $this->Inventory_subcategory->find('all', array(
                'conditions' => array('cat_id' => $cat_id, 'status' => 1),
                'order' => array('name' => 'asc')
            ));
            if (!empty($subcategories)) {
                $options[$cat_name] = [];
                foreach ($subcategories as $subcategory) {
                    $subcat_id = $subcategory['Inventory_subcategory']['id'];
                    $subcat_name = $subcategory['Inventory_subcategory']['name'];
                    if ($subcat_id == $selectedcatId  && $selectedType == 'sub') {
                        $selectedcategory = $subcategory['Inventory_subcategory'];
                        $selectedcategory['_type'] = 'sub';
                    }
                    $options[$cat_name]["sub_$subcat_id"] = $subcat_name;
                    
                }
            } else {
                if ($cat_id == $selectedcatId && $selectedType == 'cat') {
                    $selectedcategory = $category['Inventory_category'];
                    $selectedcategory['_type'] = 'cat';
                }
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        
        if (!empty($selectedcategory)) {
            $key_prefix = ($selectedcategory['_type'] == 'sub') ? 'sub_' : 'cat_';
            $options = array($key_prefix . $selectedcategory['id'] => $selectedcategory['name']) + $options;
        }
// print_r($options);exit;
        $this->set(compact('categories', 'subcategories', 'taxes', 'units', 'options', 'selectedcatId','conunits'));
        

        
        if ($this->data['User']['id']!='') {
            
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_sku?id='.$id));
            }
            $brand = $this->data['User']['brand'];
            $unit = $this->data['User']['unit'];
            $price = $this->data['User']['price'];
            $remarks = $this->data['User']['remarks'];
            $item_type = $this->data['User']['item_type'];
            $conunit = $this->data['User']['conunit'];
            $factor = $this->data['User']['factor'];
            $conprice = $this->data['User']['conprice'];
            $stock = $this->data['User']['stock'] ?? 0;
                
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $this->data['User']['category'] ?? '';
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Inventory_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Inventory_category']['name'];
                }
            }elseif (strpos($categoryInput, 'sub_') === 0) {
                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Inventory_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Inventory_subcategory']['name'];
                    $category_id = $subcatData['Inventory_subcategory']['cat_id'];
                    $category_name = $this->Inventory_category->field('name', ['id' => $category_id]);
                }
            }else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Inventory_category->create();
                if ($this->Inventory_category->save(['name' => $newcat,
                    'sync' => 0,
                    'local_sync' => 0])) {
                    $category_id = $this->Inventory_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
            
            $unitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$unit)));
            $unit_name=$unitname['Catalog_unit']['name'];
            $moq=$this->data['User']['moq'];
            
            if($conunit){
                $conunitnames=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$conunit)));
                $conunitname=$conunitnames['Catalog_unit']['name'];
            }else{
                $conunit=0;
                $factor=0;
                $conprice=0;
                $conunitname='';
            }
            $this->Inventory_sku->query("UPDATE inventory_skus SET consumption_unit_id='$conunit',consumption_unit_name='$conunitname',consumption_factor='$factor',consumption_unit_price='$conprice',item_type='$item_type',moq='$moq',stock='$stock', cat_id='$category_id',cat_name='$category_name',subcat_id='$subcategory_id',subcat_name='$subcategory_name',name ='$name',brand='$brand',unit='$unit',unit_name='$unit_name',price='$price',remarks='$remarks',sync = 0,local_sync=0 WHERE id =". $id);
            //tax Update
            $this->Inventory_sku_tax->query("UPDATE inventory_sku_tax set status=0,sync = 0,local_sync=0 WHERE product_id =". $id);
            
            $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
            foreach ($taxes as $taxess) {
                $taxID = $taxess['Inventory_tax']['id'];
                if (!empty($this->request->data['User']['tax_' . $taxID])) {
                    $selectedTaxes[] = $this->request->data['User']['tax_' . $taxID];
                    $taxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('id'=>$taxID)));
                    if($taxdetail){
                        $data['Inventory_sku_tax']=array(
                            'product_id'=>$id,
                            'product_name'=>$name,
                            'tax_id'=>$taxID,
                            'tax_name'=>$taxdetail['Inventory_tax']['name'],
                            'tax_percentage'=>$taxdetail['Inventory_tax']['percentage'],
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_sku_tax->saveAll($data['Inventory_sku_tax']))
                        {
                            
                        }else{
                            $this->Flash->error(__('SKU tax could not be saved. Please, try again.'));
                        }
                    }
                }
            }
            
            if(isset($_POST['tax_name'])){
                
                $taxnames=$_POST['tax_name'];
                $taxvalues=$_POST['tax_value'];
                   
                for ($i = 0; $i < count($taxnames); $i++) {
                    $taxname = $taxnames[$i];
                    $percentage = $taxvalues[$i];
                    
                    $newtaxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('name'=>$taxname,'percentage'=>$percentage)));
                    if(empty($newtaxdetail)){
                        $data['Inventory_tax']=array(
                            'name'=>$taxname,
                            'percentage'=>$percentage,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_tax->saveAll($data['Inventory_tax']))
                        {
                            $taxlastInsertedID = $this->Inventory_tax->id;
                    
                        } else {
                            $this->Flash->error(__('New Tax could not be saved. Please, try again.'));
                        }
                    }
                    
                    $data['Inventory_sku_tax']=array(
                        'product_id'=>$id,
                        'product_name'=>$name,
                        'tax_id'=>$taxlastInsertedID,
                        'tax_name'=>$taxname,
                        'tax_percentage'=>$percentage,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_sku_tax->saveAll($data['Inventory_sku_tax']))
                    {
                        
                    }else{
                        $this->Flash->error(__('SKU New tax could not be saved. Please, try again.'));
                    }
                    
                }
            }
            
            $this->Flash->success(__('Sku has been Updated.'));
            return $this->redirect(array('action' => 'sku_list'));
        }
        
    }
    
    public function view_sku()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $products = $this->Inventory_sku->query("SELECT * FROM inventory_skus where id=$id");
        $this->set(compact('products'));
        
        $taxes=$this->Inventory_sku_tax->query("SELECT CONCAT(tax_name, '(', tax_percentage, '%)') as taxname ,id FROM inventory_sku_tax where product_id=$id and status=1");
        $this->set(compact('taxes'));               
    }
    
    public function create_vendor()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $locationCondition = ['status' => 1,'type !='=>'DC']; // always filter by active locations
        
        if ($userRole !== 'admin') {
            // If $userLocationId is a single ID, make it an array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
        }

        $areas=$this->Location->find('all',array('conditions'=>$locationCondition));
        $this->set(compact('areas'));
        
        $indiaStates=states;
        $this->set(compact('indiaStates'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_vendor'));
            }
            
            $office_address = $this->data['User']['office_address'];
            $email = $this->data['User']['email'];
            $company = $this->data['User']['company'];
            $gst = $this->data['User']['gst'];
            $bank_ac = $this->data['User']['bank_ac'];
            $bank_name = $this->data['User']['bank_name'];
            $advance_percentage = $this->data['User']['advance_percentage'];
            $mobile = $this->data['User']['mobile'];
            $landline = $this->data['User']['landline'];
            $state = $this->data['User']['state'];
            $pan = $this->data['User']['pan'];
            $tan = $this->data['User']['tan'];
            $ifsc = $this->data['User']['ifsc'];
            $payment_days = $this->data['User']['payment_days'];
            $approval = $this->data['User']['approval'];
            
            $gstfilename='';
            $gst_image=$this->data['User']['gst_image'];
            if (!empty($gst_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$gst_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($gst_image['tmp_name'], $uploadFile)) {
                    $gstfilename=$file;
                }
            }
            
            $agreementfilename='';
            $agreement_image=$this->data['User']['agreement_image'];
            if (!empty($agreement_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$agreement_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($agreement_image['tmp_name'], $uploadFile)) {
                    $agreementfilename=$file;
                }
            }
            
            $panfilename='';
            $pan_image=$this->data['User']['pan_image'];
            if (!empty($pan_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$pan_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($pan_image['tmp_name'], $uploadFile)) {
                    $panfilename=$file;
                }
            }
            
            $tanfilename='';
            $tan_image=$this->data['User']['tan_image'];
            if (!empty($tan_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$tan_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($tan_image['tmp_name'], $uploadFile)) {
                    $tanfilename=$file;
                }
            }
            
            $fssaifilename='';
            $fssai_image=$this->data['User']['fssai_image'];
            if (!empty($fssai_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$fssai_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($fssai_image['tmp_name'], $uploadFile)) {
                    $fssaifilename=$file;
                }
            }
            
            $data['Inventory_vendor']=array(
                'name'=>$name,
                'mobile'=>$mobile,
                'landline'=>$landline,
                'email'=>$email,
                'office_address'=>$office_address,
                'state'=>$state,
                'company'=>$company,
                'pan'=>$pan,
                'gst'=>$gst,
                'tan'=>$tan,
                'bank_ac'=>$bank_ac,
                'ifsc'=>$ifsc,
                'bank_name'=>$bank_name,
                'advance_percentage'=>$advance_percentage,
                'payment_days'=>$payment_days,
                'pan_image'=>$panfilename,
                'gst_image'=>$gstfilename,
                'tan_image'=>$tanfilename,
                'agreement_image'=>$agreementfilename,
                'po_approval_required'=>$approval,
                'fssai_image'=>$fssaifilename,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Inventory_vendor->saveAll($data['Inventory_vendor']))
            {
                $lastInsertedID = $this->Inventory_vendor->id;
                
                $areas=$this->Location->find('all',array('conditions'=>array('status'=>1)));
                foreach ($areas as $area) {
                    $ID = $area['Location']['id'];
                    if (!empty($this->request->data['User']['area_' . $ID])) {
                        $selectedarea[] = $this->request->data['User']['area_' . $ID];
                        $areadetail=$this->Location->find('first',array('conditions'=>array('id'=>$ID)));
                        if($areadetail){
                            $data['Inventory_vendor_service_area']=array(
                                'vendor_id'=>$lastInsertedID,
                                'area_id'=>$ID,
                                'area_name'=>$areadetail['Location']['name'],
                                'sync' => 0,
                                'local_sync' => 0
                            );
                            
                            if($this->Inventory_vendor_service_area->saveAll($data['Inventory_vendor_service_area']))
                            {
                                
                            }else{
                                $this->Flash->error(__('area could not be saved. Please, try again.'));
                            }
                        }
                    }
                }
                
                $this->Flash->success(__('Vendor has been saved.'));
                return $this->redirect(array('action' => 'map_vendor_with_sku?id='.$lastInsertedID));
            } else {
                $this->Flash->error(__('Sku could not be saved. Please, try again.'));
            }
        }
        
    }
    
    public function vendor_list()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;


        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $locationCondition = '';
        if ($userRole !== 'admin' && $userRole !== 'subadmin') {
            $locationCondition = "and id IN (SELECT vendor_id FROM `inventory_vendor_service_areas` WHERE area_id IN (" . $userLocationId . "))";
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Inventory_vendor->query("SELECT * FROM inventory_vendors where created between '$startDatetime' and  '$endDatetime' $locationCondition ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function edit_vendor()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $locationCondition = ['status' => 1,'type !='=>'DC']; // always filter by active locations
        
        $indiaStates=states;
        $this->set(compact('indiaStates'));
        
        if ($userRole !== 'admin') {
            // If $userLocationId is a single ID, make it an array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
        }

        $areas=$this->Location->find('all',array('conditions'=>$locationCondition));
        $this->set(compact('areas'));
        $id=$_REQUEST['id'];
    
        $products = $this->Inventory_vendor->query("SELECT * FROM inventory_vendors where id=$id");
        $this->set(compact('products'));
        
        $vendor_areas=$this->Inventory_vendor_service_area->find('all',array('conditions'=>array('vendor_id'=>$id,'status'=>1),'order'=>array('id'=>'desc')));
        $this->set(compact('vendor_areas'));
        
        if ($this->data['User']['id']!='') {
            
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_vendor?id='.$id));
            }
            $email = $this->data['User']['email'];
            $office_address = $this->data['User']['office_address'];
            $company = $this->data['User']['company'];
            $gst = $this->data['User']['gst'];
            $bank_ac = $this->data['User']['bank_ac'];
            $bank_name = $this->data['User']['bank_name'];
            $advance_percentage = $this->data['User']['advance_percentage'];
            $mobile = $this->data['User']['mobile'];
            $landline = $this->data['User']['landline'];
            $state = $this->data['User']['state'];
            $pan = $this->data['User']['pan'];
            $tan = $this->data['User']['tan'];
            $ifsc = $this->data['User']['ifsc'];
            $payment_days = $this->data['User']['payment_days'];
            $approval=$this->data['User']['approval'];
            
            $gst_image=$this->data['User']['gst_image'];
            if (!empty($gst_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$gst_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($gst_image['tmp_name'], $uploadFile)) {
                    $gstfilename=$file;
                    $this->Inventory_vendor->query("UPDATE inventory_vendors SET gst_image='$gstfilename',sync = 0,local_sync=0 WHERE id =". $id);
                }
            }
            
            $agreement_image=$this->data['User']['agreement_image'];
            if (!empty($agreement_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$agreement_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($agreement_image['tmp_name'], $uploadFile)) {
                    $agreementfilename=$file;
                    $this->Inventory_vendor->query("UPDATE inventory_vendors SET agreement_image='$agreementfilename',sync = 0,local_sync=0 WHERE id =". $id);
                }
            }
            
            $pan_image=$this->data['User']['pan_image'];
            if (!empty($pan_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$pan_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($pan_image['tmp_name'], $uploadFile)) {
                    $panfilename=$file;
                    $this->Inventory_vendor->query("UPDATE inventory_vendors SET pan_image='$panfilename',sync = 0,local_sync=0 WHERE id =". $id);
                }
            }
            
            $tan_image=$this->data['User']['tan_image'];
            if (!empty($tan_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$tan_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($tan_image['tmp_name'], $uploadFile)) {
                    $tanfilename=$file;
                    $this->Inventory_vendor->query("UPDATE inventory_vendors SET tan_image='$tanfilename',sync = 0,local_sync=0 WHERE id =". $id);
                }
            }
            
            $fssai_image=$this->data['User']['fssai_image'];
            if (!empty($fssai_image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'vendor_images' . DS;
                $file=basename(time().$fssai_image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($fssai_image['tmp_name'], $uploadFile)) {
                    $fssaifilename=$file;
                    $this->Inventory_vendor->query("UPDATE inventory_vendors SET fssai_image='$fssaifilename',sync = 0,local_sync=0 WHERE id =". $id);
                }
            }
            
            $this->Inventory_vendor->query("UPDATE inventory_vendors SET po_approval_required='$approval',name ='$name',mobile='$mobile',landline='$landline',email='$email',office_address='$office_address',state='$state',company='$company',pan='$pan',gst='$gst',tan='$tan',bank_ac='$bank_ac',ifsc='$ifsc',bank_name='$bank_name',advance_percentage='$advance_percentage',payment_days='$payment_days',sync = 0,local_sync=0 WHERE id =". $id);
            
            $prevareas=$this->Inventory_vendor_service_area->query("update inventory_vendor_service_areas set status=0,sync = 0,local_sync=0 where vendor_id=$id");
            
            $areas=$this->Location->find('all',array('conditions'=>array('status'=>1)));
            foreach ($areas as $area) {
                $ID = $area['Location']['id'];
                if (!empty($this->request->data['User']['area_' . $ID])) {
                    $selectedarea[] = $this->request->data['User']['area_' . $ID];
                    $areadetail=$this->Location->find('first',array('conditions'=>array('id'=>$ID)));
                    if($areadetail){
                        $data['Inventory_vendor_service_area']=array(
                            'vendor_id'=>$id,
                            'area_id'=>$ID,
                            'area_name'=>$areadetail['Location']['name'],
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_vendor_service_area->saveAll($data['Inventory_vendor_service_area']))
                        {
                            
                        }else{
                            $this->Flash->error(__('area could not be saved. Please, try again.'));
                        }
                    }
                }
            }
            
            $this->Flash->success(__('Vendor has been Updated.'));
            return $this->redirect(array('action' => 'vendor_list'));
        }
        
    }
    
    public function view_vendor()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $products = $this->Inventory_vendor->query("SELECT * FROM inventory_vendors where id=$id");
        $this->set(compact('products'));
        
        $areas=$this->Inventory_vendor_service_area->query("SELECT area_name,id FROM inventory_vendor_service_areas where vendor_id=$id and status=1");
        $this->set(compact('areas'));               
    }
    
    
    public function map_vendor_with_sku() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
         
        if(isset($_POST['checkedData'])){
            $checkeddatas = JSON_decode($_POST['checkedData'], true);
            $vendor_id_reset = isset($_POST['vendor_id_reset']) ? intval($_POST['vendor_id_reset']) : 0;

            // Always reset existing mappings for this vendor first (enables full re-selection)
            if ($vendor_id_reset) {
                $this->Inventory_vendor_sku_served->query(
                    "UPDATE inventory_vendor_sku_served SET status=0, sync=0, local_sync=0 WHERE vendor_id = " . $vendor_id_reset
                );
            }
             
            foreach($checkeddatas as $checkeddata){
                $skuid    = $checkeddata['id'];
                $price    = $checkeddata['price'];
                $sku_name = $checkeddata['sku_name'];
                $sku_brand = $checkeddata['sku_brand'];
                $unit_name = $checkeddata['unit_name'];
                $unit_id   = $checkeddata['unit_id'];
                $vendor_id = $checkeddata['vendor_id'];
                
                $data['Inventory_vendor_sku_served'] = array(
                    'sku_name'     => $sku_name,
                    'sku_brand'    => $sku_brand,
                    'sku_unit_name'=> $unit_name,
                    'sku_unit'     => $unit_id,
                    'vendor_id'    => $vendor_id,
                    'skus_id'      => $skuid,
                    'sku_price'    => $price,
                    'sync'         => 0,
                    'local_sync'   => 0
                );
                
                if($this->Inventory_vendor_sku_served->saveAll($data['Inventory_vendor_sku_served'])){
                    // saved
                }else{
                    $this->Flash->error(__('sku could not be saved. Please, try again.'));
                }
            }
            $this->Flash->success(__('SKUs mapped successfully.')); 
        return $this->redirect(['controller' => 'dashboard', 'action' => 'vendor_list']);

        }else{
            $id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
            $user = "SELECT *, (SELECT sku_price FROM `inventory_vendor_sku_served`
                          WHERE vendor_id=$id AND skus_id=inventory_skus.id AND status=1 LIMIT 1) AS vendor_price
                   FROM `inventory_skus`
                   WHERE inventory_skus.status=1
                   ORDER BY inventory_skus.name ASC"; 
            $users = $this->Inventory_sku->query($user);
            $this->set(compact('users'));
            $this->set(compact('id'));
        }
    }
    
    public function create_semifinished()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $units=$this->Catalog_unit->find('all',array('conditions'=>array('status'=>1)));
        $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
        
        $categorys = $this->Inventory_category->find('all', ['conditions' => ['status' => 1]]);
        
        $options = [];
        foreach ($categorys as $category) {
            $cat_id = $category['Inventory_category']['id'];
            $cat_name = $category['Inventory_category']['name'];
        
            $subcategorys = $this->Inventory_subcategory->find('all', [
                'conditions' => ['cat_id' => $cat_id, 'status' => 1]
            ]);
        
            if (!empty($subcategorys)) {
                foreach ($subcategorys as $sub) {
                    $sub_id = $sub['Inventory_subcategory']['id'];
                    $sub_name = $sub['Inventory_subcategory']['name'];
                    $options[$cat_name]["sub_$sub_id"] = $sub_name;
                }
            } else {
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        $this->set(compact('categorys', 'subcategorys', 'units', 'taxes', 'options'));

    
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_semifinished'));
            }
            
            $name = $this->data['User']['name'];
            $unit = $this->data['User']['unit'];
            $price = $this->data['User']['price'];
            $remarks = $this->data['User']['remarks'];
            
            $conunit = $this->data['User']['conunit'];
            $factor = $this->data['User']['factor'];
            $conprice = $this->data['User']['conprice'];
            
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $this->data['User']['category'] ?? '';
            
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Inventory_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Inventory_category']['name'];
                }
                
            } elseif (strpos($categoryInput, 'sub_') === 0) {

                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Inventory_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Inventory_subcategory']['name'];
                    $category_id = $subcatData['Inventory_subcategory']['cat_id'];
                    $category_name = $this->Inventory_category->field('name', ['id' => $category_id]);
                }
            } else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Inventory_category->create();
                if ($this->Inventory_category->save(['name' => $newcat,
                    'sync' => 0,
                    'local_sync' => 0])) {
                    $category_id = $this->Inventory_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
            
            $unitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$unit)));
            $conunitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$conunit)));

            $data['Inventory_semifinished']=array(
                'name'=>$name,
                'unit'=>$unit,
                'cat_id' => $category_id,
                'cat_name' => $category_name,
                'subcat_id' => $subcategory_id,
                'subcat_name' => $subcategory_name,
                'unit_name'=>$unitname['Catalog_unit']['name'],
                'price'=>$price,
                'consumption_unit_id'=>$conunit,
                'consumption_unit_name'=>$conunitname['Catalog_unit']['name'],
                'consumption_factor'=>$factor,
                'consumption_unit_price'=>$conprice,
                'remarks'=>$remarks,
                'moq' => $this->data['User']['moq'] ?? 0,
                'stock' => $this->data['User']['stock'] ?? 0,
                'sync' => 0,
                'local_sync' => 0
            );
            
            if($this->Inventory_semifinished->saveAll($data['Inventory_semifinished']))
            {
                $lastInsertedID = $this->Inventory_semifinished->id;
                
                $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
                foreach ($taxes as $taxess) {
                    $taxID = $taxess['Inventory_tax']['id'];
                    if (!empty($this->request->data['User']['tax_' . $taxID])) {
                        $selectedTaxes[] = $this->request->data['User']['tax_' . $taxID];
                        $taxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('id'=>$taxID)));
                        if($taxdetail){
                            $data['Inventory_semifinished_tax']=array(
                                'product_id'=>$lastInsertedID,
                                'product_name'=>$name,
                                'tax_id'=>$taxID,
                                'tax_name'=>$taxdetail['Inventory_tax']['name'],
                                'tax_percentage'=>$taxdetail['Inventory_tax']['percentage'],
                                'sync' => 0,
                                'local_sync' => 0
                            );
                            
                            if($this->Inventory_semifinished_tax->saveAll($data['Inventory_semifinished_tax']))
                            {
                                
                            }else{
                                $this->Flash->error(__('Semi-Finished tax could not be saved. Please, try again.'));
                            }
                        }
                    }
                }
                
                if(isset($_POST['custom_tax_name'])){
                
                    $taxnames=$_POST['custom_tax_name'];
                    $taxvalues=$_POST['custom_tax_value'];
                       
                    for ($i = 0; $i < count($taxnames); $i++) {
                        $taxname = $taxnames[$i];
                        $percentage = $taxvalues[$i];
                        
                        $newtaxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('name'=>$taxname,'percentage'=>$percentage)));
                        if(empty($newtaxdetail)){
                            $data['Inventory_tax']=array(
                                'name'=>$taxname,
                                'percentage'=>$percentage,
                                'sync' => 0,
                                'local_sync' => 0
                            );
                            
                            if($this->Inventory_tax->saveAll($data['Inventory_tax']))
                            {
                                $taxlastInsertedID = $this->Inventory_tax->id;
                        
                            } else {
                                $this->Flash->error(__('New Tax could not be saved. Please, try again.'));
                            }
                        }
                        
                        $data['Inventory_semifinished_tax']=array(
                            'product_id'=>$lastInsertedID,
                            'product_name'=>$name,
                            'tax_id'=>$taxlastInsertedID,
                            'tax_name'=>$taxname,
                            'tax_percentage'=>$percentage,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_semifinished_tax->saveAll($data['Inventory_semifinished_tax']))
                        {
                            
                        }else{
                            $this->Flash->error(__('Semi-Finished New tax could not be saved. Please, try again.'));
                        }
                        
                    }
                }
                $this->Flash->success(__('Semi-Finished has been saved.'));
                return $this->redirect(array('action' => 'semifinished_list'));
            } else {
                $this->Flash->error(__('Semi-Finished could not be saved. Please, try again.'));
            }
        }
        
    }
    /*
    public function semifinished_list()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    */

    public function semifinished_list()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Inventory_semifinished->query("SELECT inventory_semifinished.*, COALESCE(vsf.batch_cost, 0) as recipe_batch_cost, COALESCE(vsf.unit_cost, 0) as recipe_unit_cost FROM inventory_semifinished LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = inventory_semifinished.id WHERE inventory_semifinished.created BETWEEN '$startDatetime' AND '$endDatetime' ORDER BY inventory_semifinished.id DESC");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }

    public function edit_semifinished()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $units=$this->Catalog_unit->find('all',array('conditions'=>array('status'=>1)));
        $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
        
       // $this->set(compact('units','taxes'));
        
        $id=$_REQUEST['id'];
    
        $products = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished where id=$id and status=1");
        $this->set(compact('products'));
        
        $product_taxes=$this->Inventory_semifinished_tax->find('all',array('conditions'=>array('product_id'=>$id,'status'=>1),'order'=>array('id'=>'desc')));
        $this->set(compact('product_taxes'));
        
        
        $categories = $this->Inventory_category->find('all', array('conditions' => array('status' => 1), 'order' => array('name' => 'asc')));

        $unit=$products[0]['inventory_semifinished']['unit'];
        $conunits=$this->Catalog_unit_mapping->find('all',array('conditions'=>array('status'=>1,'unit_id'=>$unit)));
        

        $options = [];
        if (!empty($products[0]['inventory_semifinished']['subcat_id'])) {
            $selectedcatId = $products[0]['inventory_semifinished']['subcat_id'];
            $selectedType = 'sub';
        } else {
            $selectedcatId = $products[0]['inventory_semifinished']['cat_id'];
            $selectedType = 'cat';
        }
        // $selectedcatId = !empty($products[0]['inventory_semifinished']['subcat_id']) ? $products[0]['inventory_semifinished']['subcat_id'] : $products[0]['inventory_semifinished']['cat_id'];
        $selectedcategory = null;
    
        foreach ($categories as $category) {
            $cat_id = $category['Inventory_category']['id'];
            $cat_name = $category['Inventory_category']['name'];
            $subcategories = $this->Inventory_subcategory->find('all', array(
                'conditions' => array('cat_id' => $cat_id, 'status' => 1),
                'order' => array('name' => 'asc')
            ));
            if (!empty($subcategories)) {
                $options[$cat_name] = [];
                foreach ($subcategories as $subcategory) {
                    $subcat_id = $subcategory['Inventory_subcategory']['id'];
                    $subcat_name = $subcategory['Inventory_subcategory']['name'];
                    if ($subcat_id == $selectedcatId  && $selectedType == 'sub') {
                        $selectedcategory = $subcategory['Inventory_subcategory'];
                        $selectedcategory['_type'] = 'sub';
                    }
                    $options[$cat_name]["sub_$subcat_id"] = $subcat_name;
                }
            } else {
                if ($cat_id == $selectedcatId  && $selectedType == 'cat') {
                    $selectedcategory = $category['Inventory_category'];
                    $selectedcategory['_type'] = 'cat';
                }
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        if (!empty($selectedcategory)) {
            $key_prefix = ($selectedcategory['_type'] == 'sub') ? 'sub_' : 'cat_';
            $options = array($key_prefix . $selectedcategory['id'] => $selectedcategory['name']) + $options;
        }

        $this->set(compact('categories', 'subcategories', 'taxes', 'units', 'options', 'selectedcatId','conunits'));
        
        if ($this->data['User']['id']!='') {
            
            $id=$this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'edit_semifinished?id='.$id));
            }
            $unit = $this->data['User']['unit'];
            $price = $this->data['User']['price'];
            $remarks = $this->data['User']['remarks'];
            $moq= $this->data['User']['moq'];
            $stock= $this->data['User']['stock'];
            
            $conunit = $this->data['User']['conunit'];
            $factor = $this->data['User']['factor'];
            $conprice = $this->data['User']['conprice'];
        
            // CATEGORY
            $category_id = null;
            $category_name = '';
            $subcategory_id = '';
            $subcategory_name = '';
            
            $categoryInput = $this->data['User']['category'] ?? '';
            
            if (strpos($categoryInput, 'cat_') === 0) {
                $category_id = (int) str_replace('cat_', '', $categoryInput);
                $catData = $this->Inventory_category->findById($category_id);
                if ($catData) {
                    $category_name = $catData['Inventory_category']['name'];
                }
            }elseif (strpos($categoryInput, 'sub_') === 0) {
                $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
                $subcatData = $this->Inventory_subcategory->findById($subcategory_id);
                if ($subcatData) {
                    $subcategory_name = $subcatData['Inventory_subcategory']['name'];
                    $category_id = $subcatData['Inventory_subcategory']['cat_id'];
                    $category_name = $this->Inventory_category->field('name', ['id' => $category_id]);
                }
            }else {
                // Treat as new category name
                $newcat = trim($categoryInput);
                $this->Inventory_category->create();
                if ($this->Inventory_category->save(['name' => $newcat,'sync' => 0,'local_sync' => 0])) {
                    $category_id = $this->Inventory_category->id;
                    $category_name = $newcat;
                } else {
                    $this->Flash->error(__('New category could not be saved. Please try again.'));
                    return;
                }
            }
            
            $unitname=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$unit)));
            $unit_name=$unitname['Catalog_unit']['name'];
            
            if($conunit){
                $conunitnames=$this->Catalog_unit->find('first',array('conditions'=>array('id'=>$conunit)));
                $conunitname=$conunitnames['Catalog_unit']['name'];
            }else{
                $conunit=0;
                $factor=0;
                $conprice=0;
                $conunitname='';
            }
            
            $this->Inventory_semifinished->query("UPDATE inventory_semifinished SET consumption_unit_id='$conunit',consumption_unit_name='$conunitname',consumption_factor='$factor',consumption_unit_price='$conprice' ,moq='$moq',stock='$stock', cat_id='$category_id',cat_name='$category_name',subcat_id='$subcategory_id',subcat_name='$subcategory_name',name ='$name',unit='$unit',unit_name='$unit_name',price='$price',remarks='$remarks',sync = 0,local_sync=0 WHERE id =". $id);
            
            //tax Update
            $this->Inventory_semifinished_tax->query("UPDATE inventory_semifinished_tax set status=0,sync=0,local_sync=0  WHERE product_id =". $id);
            
            $taxes=$this->Inventory_tax->find('all',array('conditions'=>array('status'=>1)));
            foreach ($taxes as $taxess) {
                $taxID = $taxess['Inventory_tax']['id'];
                if (!empty($this->request->data['User']['tax_' . $taxID])) {
                    $selectedTaxes[] = $this->request->data['User']['tax_' . $taxID];
                    $taxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('id'=>$taxID)));
                    if($taxdetail){
                        $data['Inventory_semifinished_tax']=array(
                            'product_id'=>$id,
                            'product_name'=>$name,
                            'tax_id'=>$taxID,
                            'tax_name'=>$taxdetail['Inventory_tax']['name'],
                            'tax_percentage'=>$taxdetail['Inventory_tax']['percentage'],
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_semifinished_tax->saveAll($data['Inventory_semifinished_tax']))
                        {
                            
                        }else{
                            $this->Flash->error(__('Semi-finished tax could not be saved. Please, try again.'));
                        }
                    }
                }
            }
            
            if(isset($_POST['tax_name'])){
                
                $taxnames=$_POST['tax_name'];
                $taxvalues=$_POST['tax_value'];
                   
                for ($i = 0; $i < count($taxnames); $i++) {
                    $taxname = $taxnames[$i];
                    $percentage = $taxvalues[$i];
                    
                    $newtaxdetail=$this->Inventory_tax->find('first',array('conditions'=>array('name'=>$taxname,'percentage'=>$percentage)));
                    if(empty($newtaxdetail)){
                        $data['Inventory_tax']=array(
                            'name'=>$taxname,
                            'percentage'=>$percentage,
                            'sync' => 0,
                            'local_sync' => 0
                        );
                        
                        if($this->Inventory_tax->saveAll($data['Inventory_tax']))
                        {
                            $taxlastInsertedID = $this->Inventory_tax->id;
                    
                        } else {
                            $this->Flash->error(__('New Tax could not be saved. Please, try again.'));
                        }
                    }
                    
                    $data['Inventory_semifinished_tax']=array(
                        'product_id'=>$id,
                        'product_name'=>$name,
                        'tax_id'=>$taxlastInsertedID,
                        'tax_name'=>$taxname,
                        'tax_percentage'=>$percentage,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_semifinished_tax->saveAll($data['Inventory_semifinished_tax']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semi-finished New tax could not be saved. Please, try again.'));
                    }
                }
            }
            
            $this->Flash->success(__('Semi-finished has been Updated.'));
            return $this->redirect(array('action' => 'semifinished_list'));
        }
        
    }
    
    public function view_semifinished()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $products = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished where id=$id and status=1");
        $this->set(compact('products'));
        
        $taxes=$this->Inventory_semifinished_tax->query("SELECT CONCAT(tax_name, '(', tax_percentage, '%)') as taxname ,id FROM inventory_semifinished_tax where product_id=$id  and status=1");
        $this->set(compact('taxes'));               
    }
    /*
    public function add_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished where id=$id");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Semifinished' and component_type='Semifinished' and status=1");
        // $skurecipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Semifinished' and component_type='Sku' and status=1");
        $skurecipes = $this->Inventory_linking->query("SELECT inventory_linking.* FROM inventory_linking INNER JOIN inventory_skus ON inventory_skus.id = inventory_linking.component_id WHERE inventory_linking.parent_id = $id AND inventory_linking.parent_type = 'Semifinished' AND inventory_linking.component_type = 'Sku' AND inventory_linking.status = 1 AND inventory_skus.item_type = 1");
        $this->set(compact('recipes'));
        $this->set(compact('recipes','skurecipes'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            if($product_id==''){
                $this->Flash->error(__('Error'));
                return $this->redirect(array('action' => 'add_recipe?id='.$product_id));
            }
            
            $product_name = $this->data['User']['name'];
            $product_unit = $this->data['User']['unit'];
            $product_unit_name = $this->data['User']['unit_name'];
            
            $yield = $this->data['User']['yield'];
            
            $this->Inventory_semifinished->updateAll(
                ['Inventory_semifinished.yield' => $yield,'sync' => 0,'local_sync' => 0],
                ['Inventory_semifinished.id' => $product_id]
            );
            
            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);

            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Semifinished',
                        'Inventory_linking.component_type' => 'Semifinished',
                    ]
                );

                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['consumption_unit_id']?$seminame['Inventory_semifinished']['consumption_unit_id']:0;
                    $semi_unit_name=$seminame['Inventory_semifinished']['consumption_unit_name']?$seminame['Inventory_semifinished']['consumption_unit_name']:'';
                    $semi_unit_price=$seminame['Inventory_semifinished']['consumption_unit_price']?$seminame['Inventory_semifinished']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$seminame['Inventory_semifinished']['unit']?$seminame['Inventory_semifinished']['unit']:0;
                    $component_purchase_unit_name=$seminame['Inventory_semifinished']['unit_name']?$seminame['Inventory_semifinished']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $semi_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$semi_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Semifinished',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$semi_quantity,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                   // print_r($data);exit;
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Semifinished',
                        'Inventory_linking.component_type' => 'Sku'
                    ]
                );

                    
                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['consumption_unit_id']?$skuname['Inventory_sku']['consumption_unit_id']:0;
                    $sku_unit_name=$skuname['Inventory_sku']['consumption_unit_name']?$skuname['Inventory_sku']['consumption_unit_name']:'';
                    $semi_unit_price=$skuname['Inventory_sku']['consumption_unit_price']?$skuname['Inventory_sku']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$skuname['Inventory_sku']['unit']?$skuname['Inventory_sku']['unit']:0;
                    $component_purchase_unit_name=$skuname['Inventory_sku']['unit_name']?$skuname['Inventory_sku']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $sku_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    // print_r($mappedUnits);exit;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$sku_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Semifinished',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$sku_quantity,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'semifinished_list'));
        }
    }
    */
    public function add_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished where id=$id");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Semifinished' and component_type='Semifinished' and status=1");
        // $skurecipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Semifinished' and component_type='Sku' and status=1");
        $skurecipes = $this->Inventory_linking->query("SELECT inventory_linking.* FROM inventory_linking INNER JOIN inventory_skus ON inventory_skus.id = inventory_linking.component_id WHERE inventory_linking.parent_id = $id AND inventory_linking.parent_type = 'Semifinished' AND inventory_linking.component_type = 'Sku' AND inventory_linking.status = 1 AND inventory_skus.item_type = 1");
        $this->set(compact('recipes'));
        $this->set(compact('recipes','skurecipes'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            if($product_id==''){
                $this->Flash->error(__('Error'));
                return $this->redirect(array('action' => 'add_recipe?id='.$product_id));
            }
            
            $product_name = $this->data['User']['name'];
            $product_unit = $this->data['User']['unit'];
            $product_unit_name = $this->data['User']['unit_name'];
            
            $yield = $this->data['User']['yield'];
            
            $this->Inventory_semifinished->updateAll(
                ['Inventory_semifinished.yield' => $yield,'sync' => 0,'local_sync' => 0],
                ['Inventory_semifinished.id' => $product_id]
            );
            
            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);

            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Semifinished',
                        'Inventory_linking.component_type' => 'Semifinished',
                    ]
                );

                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['consumption_unit_id']?$seminame['Inventory_semifinished']['consumption_unit_id']:0;
                    $semi_unit_name=$seminame['Inventory_semifinished']['consumption_unit_name']?$seminame['Inventory_semifinished']['consumption_unit_name']:'';
                    $semi_unit_price=$seminame['Inventory_semifinished']['consumption_unit_price']?$seminame['Inventory_semifinished']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$seminame['Inventory_semifinished']['unit']?$seminame['Inventory_semifinished']['unit']:0;
                    $component_purchase_unit_name=$seminame['Inventory_semifinished']['unit_name']?$seminame['Inventory_semifinished']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $semi_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$semi_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Semifinished',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$semi_quantity,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                   // print_r($data);exit;
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Semifinished',
                        'Inventory_linking.component_type' => 'Sku'
                    ]
                );

                    
                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['consumption_unit_id']?$skuname['Inventory_sku']['consumption_unit_id']:0;
                    $sku_unit_name=$skuname['Inventory_sku']['consumption_unit_name']?$skuname['Inventory_sku']['consumption_unit_name']:'';
                    $semi_unit_price=$skuname['Inventory_sku']['consumption_unit_price']?$skuname['Inventory_sku']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$skuname['Inventory_sku']['unit']?$skuname['Inventory_sku']['unit']:0;
                    $component_purchase_unit_name=$skuname['Inventory_sku']['unit_name']?$skuname['Inventory_sku']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $sku_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    // print_r($mappedUnits);exit;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$sku_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Semifinished',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$sku_quantity,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'semifinished_list'));
        }
    }
    
    public function fetch_skus_options() {
        $this->autoRender = false; // Disable view rendering
        $skuss=array();
        $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
        foreach($skus as $sku){
            $skuss[]=$sku['Inventory_sku'];
        }
        $responseArray = array('response_code' => 1, 'data' => $skuss);
        echo json_encode($responseArray);

    }
    /*
    public function product_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product where id=$id");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Product' and component_type='Semifinished' and status = 1 ");
        $skurecipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Product' and component_type='Sku' and status = 1");
        $this->set(compact('recipes','skurecipes'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            if($product_id==''){
                $this->Flash->error(__('Product Error'));
                return $this->redirect(array('action' => 'product_recipe?id='.$semi_id));
            }
            
            $product_name = $this->data['User']['name'];
            $product_unit = $this->data['User']['unit'];
            $product_unit_name = $this->data['User']['unit_name'];
            $yield = 1;
            
            $this->Catalog_product->updateAll(
                ['Catalog_product.yield' => $yield,'sync' => 0,'local_sync' => 0],
                ['Catalog_product.id' => $product_id]
            );

            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);
            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0, 
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Semifinished',
                    ]
                );
    
                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['consumption_unit_id']?$seminame['Inventory_semifinished']['consumption_unit_id']:0;
                    $semi_unit_name=$seminame['Inventory_semifinished']['consumption_unit_name']?$seminame['Inventory_semifinished']['consumption_unit_name']:'';
                    $semi_unit_price=$seminame['Inventory_semifinished']['consumption_unit_price']?$seminame['Inventory_semifinished']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$seminame['Inventory_semifinished']['unit']?$seminame['Inventory_semifinished']['unit']:0;
                    $component_purchase_unit_name=$seminame['Inventory_semifinished']['unit_name']?$seminame['Inventory_semifinished']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $semi_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$semi_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }

                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$semi_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0

                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){

                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Sku',
                    ]
                );
    
  
                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['consumption_unit_id']?$skuname['Inventory_sku']['consumption_unit_id']:0;
                    $sku_unit_name=$skuname['Inventory_sku']['consumption_unit_name']?$skuname['Inventory_sku']['consumption_unit_name']:'';
                    $semi_unit_price=$skuname['Inventory_sku']['consumption_unit_price']?$skuname['Inventory_sku']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$skuname['Inventory_sku']['unit']?$skuname['Inventory_sku']['unit']:0;
                    $component_purchase_unit_name=$skuname['Inventory_sku']['unit_name']?$skuname['Inventory_sku']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $sku_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$sku_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$sku_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'product_list'));
        }
        
    }
    */
   /* public function product_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product where id=$id");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query("SELECT inventory_linking.*, COALESCE(vsf.unit_cost, 0) as live_price, ROUND(inventory_linking.conversion_quantity * COALESCE(vsf.unit_cost, 0), 2) as line_cost FROM inventory_linking LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.name = inventory_linking.component_name WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product' AND inventory_linking.component_type='Semifinished' AND inventory_linking.status=1");
        $skurecipes = $this->Inventory_linking->query("SELECT inventory_linking.*, COALESCE(vsp.unit_price, 0) as live_price, ROUND(inventory_linking.conversion_quantity * COALESCE(vsp.unit_price, 0), 2) as line_cost FROM inventory_linking LEFT JOIN v_sku_unit_prices vsp ON vsp.sku_name = inventory_linking.component_name WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product' AND inventory_linking.component_type='Sku' AND inventory_linking.status=1");
        $recipe_total_cost = $this->Inventory_linking->query("SELECT COALESCE(vpc.recipe_cost,0) as total_cost FROM catalog_product cp LEFT JOIN v_product_recipe_cost vpc ON vpc.id=cp.id WHERE cp.id=$id");
        $this->set(compact('recipes','skurecipes','recipe_total_cost'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            if($product_id==''){
                $this->Flash->error(__('Product Error'));
                return $this->redirect(array('action' => 'product_recipe?id='.$semi_id));
            }
            
            $product_name = $this->data['User']['name'];
            $product_unit = $this->data['User']['unit'];
            $product_unit_name = $this->data['User']['unit_name'];
            $yield = 1;
            
            $this->Catalog_product->updateAll(
                ['Catalog_product.yield' => $yield,'sync' => 0,'local_sync' => 0],
                ['Catalog_product.id' => $product_id]
            );

            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);
            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0, 
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Semifinished',
                    ]
                );
    
                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['consumption_unit_id']?$seminame['Inventory_semifinished']['consumption_unit_id']:0;
                    $semi_unit_name=$seminame['Inventory_semifinished']['consumption_unit_name']?$seminame['Inventory_semifinished']['consumption_unit_name']:'';
                    $semi_unit_price=$seminame['Inventory_semifinished']['consumption_unit_price']?$seminame['Inventory_semifinished']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$seminame['Inventory_semifinished']['unit']?$seminame['Inventory_semifinished']['unit']:0;
                    $component_purchase_unit_name=$seminame['Inventory_semifinished']['unit_name']?$seminame['Inventory_semifinished']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $semi_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$semi_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }

                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$semi_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0

                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){

                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Sku',
                    ]
                );
    
  
                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['consumption_unit_id']?$skuname['Inventory_sku']['consumption_unit_id']:0;
                    $sku_unit_name=$skuname['Inventory_sku']['consumption_unit_name']?$skuname['Inventory_sku']['consumption_unit_name']:'';
                    $semi_unit_price=$skuname['Inventory_sku']['consumption_unit_price']?$skuname['Inventory_sku']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$skuname['Inventory_sku']['unit']?$skuname['Inventory_sku']['unit']:0;
                    $component_purchase_unit_name=$skuname['Inventory_sku']['unit_name']?$skuname['Inventory_sku']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $sku_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$sku_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$sku_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'product_list'));
        }
        
    }
    */
	
	public function product_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product where id=$id");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query(
            "SELECT inventory_linking.*,
                COALESCE(vsf.unit_cost, 0) AS live_price,
                ROUND(inventory_linking.conversion_quantity * COALESCE(vsf.unit_cost, 0), 2) AS line_cost
             FROM inventory_linking
             LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = CAST(inventory_linking.component_id AS UNSIGNED)
             WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product'
               AND inventory_linking.component_type='Semifinished' AND inventory_linking.status=1"
        );
		
        $skurecipes = $this->Inventory_linking->query(
            "SELECT inventory_linking.*,
                COALESCE(
                    (SELECT CAST(sl.sku_price AS DECIMAL(15,6))
                     FROM stock_ledger sl
                     WHERE sl.sku_id = sk.id AND sl.record_type = 'stockin'
                       AND CAST(sl.sku_price AS DECIMAL(15,6)) > 0
                     ORDER BY sl.id DESC LIMIT 1)
                    / GREATEST(COALESCE(
                        (SELECT CAST(um.conversion_factor AS DECIMAL(15,6))
                         FROM catalog_unit_mapping um
                         WHERE um.unit_name        = sk.unit_name
                           AND um.mapped_unit_name = sk.consumption_unit_name
                           AND um.unit_name       != um.mapped_unit_name
                           AND um.status = 1
                         ORDER BY um.id DESC LIMIT 1),
                        NULLIF(CAST(sk.consumption_factor AS DECIMAL(15,6)), 0),
                        1
                    ), 1),
                    sk.consumption_unit_price, 0) AS live_price,
                ROUND(inventory_linking.conversion_quantity * COALESCE(
                    (SELECT CAST(sl.sku_price AS DECIMAL(15,6))
                     FROM stock_ledger sl
                     WHERE sl.sku_id = sk.id AND sl.record_type = 'stockin'
                       AND CAST(sl.sku_price AS DECIMAL(15,6)) > 0
                     ORDER BY sl.id DESC LIMIT 1)
                    / GREATEST(COALESCE(
                        (SELECT CAST(um.conversion_factor AS DECIMAL(15,6))
                         FROM catalog_unit_mapping um
                         WHERE um.unit_name        = sk.unit_name
                           AND um.mapped_unit_name = sk.consumption_unit_name
                           AND um.unit_name       != um.mapped_unit_name
                           AND um.status = 1
                         ORDER BY um.id DESC LIMIT 1),
                        NULLIF(CAST(sk.consumption_factor AS DECIMAL(15,6)), 0),
                        1
                    ), 1),
                    sk.consumption_unit_price, 0), 2) AS line_cost
             FROM inventory_linking
             LEFT JOIN inventory_skus sk ON CAST(sk.id AS CHAR) = inventory_linking.component_id
             WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product'
               AND inventory_linking.component_type='Sku' AND inventory_linking.status=1"
        );
        $recipe_total_cost = $this->Inventory_linking->query(
            "SELECT
                COALESCE(
                    (SELECT SUM(inventory_linking.conversion_quantity * COALESCE(
                        (SELECT CAST(sl.sku_price AS DECIMAL(15,6))
                         FROM stock_ledger sl
                         WHERE sl.sku_id = sk.id AND sl.record_type = 'stockin'
                           AND CAST(sl.sku_price AS DECIMAL(15,6)) > 0
                         ORDER BY sl.id DESC LIMIT 1)
                        / GREATEST(COALESCE(
                            (SELECT CAST(um.conversion_factor AS DECIMAL(15,6))
                             FROM catalog_unit_mapping um
                             WHERE um.unit_name        = sk.unit_name
                               AND um.mapped_unit_name = sk.consumption_unit_name
                               AND um.unit_name       != um.mapped_unit_name
                               AND um.status = 1
                             ORDER BY um.id DESC LIMIT 1),
                            NULLIF(CAST(sk.consumption_factor AS DECIMAL(15,6)), 0),
                            1
                        ), 1),
                        sk.consumption_unit_price, 0))
                     FROM inventory_linking
                     LEFT JOIN inventory_skus sk ON CAST(sk.id AS CHAR) = inventory_linking.component_id
                     WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product'
                       AND inventory_linking.component_type='Sku' AND inventory_linking.status=1), 0)
                + COALESCE(
                    (SELECT SUM(inventory_linking.conversion_quantity * COALESCE(vsf.unit_cost, 0))
                     FROM inventory_linking
                     LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = CAST(inventory_linking.component_id AS UNSIGNED)
                     WHERE inventory_linking.parent_id=$id AND inventory_linking.parent_type='Product'
                       AND inventory_linking.component_type='Semifinished' AND inventory_linking.status=1), 0)
             AS total_cost"
        );
        $this->set(compact('recipes','skurecipes','recipe_total_cost'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            if($product_id==''){
                $this->Flash->error(__('Product Error'));
                return $this->redirect(array('action' => 'product_recipe?id='.$semi_id));
            }
            
            $product_name = $this->data['User']['name'];
            $product_unit = $this->data['User']['unit'];
            $product_unit_name = $this->data['User']['unit_name'];
            $yield = 1;
            
            $this->Catalog_product->updateAll(
                ['Catalog_product.yield' => $yield,'sync' => 0,'local_sync' => 0],
                ['Catalog_product.id' => $product_id]
            );

            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);
            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0, 
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Semifinished',
                    ]
                );
    
                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['consumption_unit_id']?$seminame['Inventory_semifinished']['consumption_unit_id']:0;
                    $semi_unit_name=$seminame['Inventory_semifinished']['consumption_unit_name']?$seminame['Inventory_semifinished']['consumption_unit_name']:'';
                    $semi_unit_price=$seminame['Inventory_semifinished']['consumption_unit_price']?$seminame['Inventory_semifinished']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$seminame['Inventory_semifinished']['unit']?$seminame['Inventory_semifinished']['unit']:0;
                    $component_purchase_unit_name=$seminame['Inventory_semifinished']['unit_name']?$seminame['Inventory_semifinished']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $semi_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$semi_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }

                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$semi_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0

                    );
                    
                    $this->Inventory_linking->create();
                    if($this->Inventory_linking->save(['Inventory_linking' => $data['Inventory_linking']]))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){

                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0,
                        'Inventory_linking.status' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Sku',
                    ]
                );
    
  
                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['consumption_unit_id']?$skuname['Inventory_sku']['consumption_unit_id']:0;
                    $sku_unit_name=$skuname['Inventory_sku']['consumption_unit_name']?$skuname['Inventory_sku']['consumption_unit_name']:'';
                    $semi_unit_price=$skuname['Inventory_sku']['consumption_unit_price']?$skuname['Inventory_sku']['consumption_unit_price']:0;
                    
                    $component_purchase_unit=$skuname['Inventory_sku']['unit']?$skuname['Inventory_sku']['unit']:0;
                    $component_purchase_unit_name=$skuname['Inventory_sku']['unit_name']?$skuname['Inventory_sku']['unit_name']:'';
                    
                    $mappedUnits = $this->Catalog_unit_mapping->find('first', [
                        'conditions' => ['mapped_unit_id' => $sku_unit,'unit_id' => $component_purchase_unit, 'status' => 1],
                        'fields' => ['conversion_factor'],
                        'recursive' => -1,
                    ]);
                    $conversion_factor=$mappedUnits['Catalog_unit_mapping']['conversion_factor']?$mappedUnits['Catalog_unit_mapping']['conversion_factor']:0;
                    if($conversion_factor>0){
                       $component_purchase_unit_quantity=$sku_quantity/$conversion_factor; 
                    }else{
                        $component_purchase_unit_quantity=0;
                    }
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Product',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'parent_yield'=>$yield,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$component_purchase_unit_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'component_price'=>$semi_unit_price,
                        'component_purchase_unit'=>$component_purchase_unit,
                        'component_purchase_unit_name'=>$component_purchase_unit_name,
                        'conversion_quantity'=>$sku_quantity,
                        'status'=>1,
                        'sync' => 0,
                        'local_sync' => 0
                    );
                    
                    $this->Inventory_linking->create();
                    if($this->Inventory_linking->save(['Inventory_linking' => $data['Inventory_linking']]))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            // Write back live recipe cost to the denormalized food_cost column
            $pCostResult = $this->Inventory_linking->query(
                "SELECT COALESCE(vpc.recipe_cost, 0) as rc FROM v_product_recipe_cost vpc WHERE vpc.id = {$product_id} LIMIT 1"
            );
            $newFoodCost = isset($pCostResult[0][0]['rc']) ? $pCostResult[0][0]['rc'] : 0;
            $this->Catalog_product->updateAll(
                ['Catalog_product.food_cost' => $newFoodCost, 'sync' => 0, 'local_sync' => 0],
                ['Catalog_product.id' => $product_id]
            );
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'product_list'));
        }
        
    }
    
	public function export_recipe_costing()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        // ── Resolve product list ──────────────────────────────────────────────
        $exportAll  = !empty($_POST['export_all']) && $_POST['export_all'] == '1';
        $idsParam   = isset($_POST['product_ids']) ? trim($_POST['product_ids']) : '';
        $productIds = [];

        if ($exportAll || $idsParam === '') {
            $rows = $this->Catalog_product->query(
                "SELECT id FROM catalog_product WHERE status = 1 ORDER BY id ASC"
            );
            foreach ($rows as $r) {
                $productIds[] = $r['catalog_product']['id'];
            }
        } else {
            foreach (explode(',', $idsParam) as $v) {
                $v = intval(trim($v));
                if ($v > 0) $productIds[] = $v;
            }
        }

        if (empty($productIds)) {
            $this->Flash->error('No products selected.');
            return $this->redirect(['action' => 'product_list']);
        }

        // ── Load recipe data per product ─────────────────────────────────────
        $products = [];
        foreach ($productIds as $pid) {
            $pRow = $this->Catalog_product->query(
                "SELECT id, name, price FROM catalog_product WHERE id = $pid LIMIT 1"
            );
            if (empty($pRow)) continue;
            $pName  = $pRow[0]['catalog_product']['name'];
            $pPrice = floatval($pRow[0]['catalog_product']['price']);

            // SKU components — use consumption_unit_price to match the recipe view
            $skuRows = $this->Inventory_linking->query(
                "SELECT il.component_name,
                        il.component_unit_name AS uom,
                        il.conversion_quantity AS req_qty,
                        COALESCE(sk.consumption_unit_price, 0) AS unit_cost,
                        COALESCE(NULLIF(CAST(sk.consumption_factor AS DECIMAL(15,4)), 0), 1) AS per_unit,
                        ROUND(il.conversion_quantity * COALESCE(sk.consumption_unit_price, 0), 4) AS line_cost,
                        'Sku' AS comp_type
                 FROM inventory_linking il
                 LEFT JOIN inventory_skus sk ON CAST(sk.id AS CHAR) = il.component_id
                 WHERE il.parent_id = $pid AND il.parent_type = 'Product'
                   AND il.component_type = 'Sku' AND il.status = 1"
            );

            // Semifinished components - use v_semifinished_recipe_cost for live unit_cost
            $semiRows = $this->Inventory_linking->query(
                "SELECT il.component_name,
                        il.component_unit_name AS uom,
                        il.conversion_quantity AS req_qty,
                        COALESCE(vsf.unit_cost, 0) AS unit_cost,
                        1 AS per_unit,
                        ROUND(il.conversion_quantity * COALESCE(vsf.unit_cost, 0), 4) AS line_cost,
                        'Semifinished' AS comp_type
                 FROM inventory_linking il
                 LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = CAST(il.component_id AS UNSIGNED)
                 LEFT JOIN inventory_semifinished sf ON sf.id = CAST(il.component_id AS UNSIGNED)
                 WHERE il.parent_id = $pid AND il.parent_type = 'Product'
                   AND il.component_type = 'Semifinished' AND il.status = 1"
            );

            $ingredients = [];
            foreach ($semiRows as $r) {
                // 'il' alias holds named cols (component_name); [0] holds computed cols (uom, line_cost, etc.)
                $merged = array_merge($r['il'] ?? $r['inventory_linking'] ?? [], $r[0] ?? []);
                $ingredients[] = array_merge($merged, ['comp_type' => 'Semifinished']);
            }
            foreach ($skuRows as $r) {
                $merged = array_merge($r['il'] ?? $r['inventory_linking'] ?? [], $r[0] ?? []);
                $ingredients[] = array_merge($merged, ['comp_type' => 'Sku']);
            }

            $totalCost = array_sum(array_column($ingredients, 'line_cost'));

            $products[] = [
                'id'          => $pid,
                'name'        => $pName,
                'price'       => $pPrice,
                'ingredients' => $ingredients,
                'total_cost'  => $totalCost,
            ];
        }

        // ── Build Excel ───────────────────────────────────────────────────────
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $xls   = new PHPExcel();
        $sheet = $xls->getActiveSheet();
        $sheet->setTitle('Recipe Costing');

        // Helper: apply style array to range
        $applyStyle = function($range, $style) use ($sheet) {
            $sheet->getStyle($range)->applyFromArray($style);
        };

        // Column widths
        $sheet->getColumnDimension('A')->setWidth(6);
        $sheet->getColumnDimension('B')->setWidth(30);
        $sheet->getColumnDimension('C')->setWidth(32);
        $sheet->getColumnDimension('D')->setWidth(8);
        $sheet->getColumnDimension('E')->setWidth(10);
        $sheet->getColumnDimension('F')->setWidth(16);
        $sheet->getColumnDimension('G')->setWidth(10);
        $sheet->getColumnDimension('H')->setWidth(14);
        $sheet->getColumnDimension('I')->setWidth(14);
        $sheet->getColumnDimension('J')->setWidth(12);

        // Main header row
        $sheet->setCellValue('A1', 'SR');
        $sheet->setCellValue('B1', 'NAME OF DISH');
        $sheet->setCellValue('C1', 'INGREDIENT');
        $sheet->setCellValue('D1', 'UOM');
        $sheet->setCellValue('E1', 'REQ QTY');
        $sheet->setCellValue('F1', 'UNIT COST');
        $sheet->setCellValue('G1', 'PER UNIT');
        $sheet->setCellValue('H1', 'COST PRICE');
        $sheet->setCellValue('I1', 'SELLING PRICE');
        $sheet->setCellValue('J1', 'MARGIN');

        $headerStyle = [
            'font'      => ['bold' => true, 'color' => ['rgb' => 'FFFFFF'], 'size' => 10],
            'fill'      => ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => '2F4F4F']],
            'alignment' => ['horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
                            'vertical'   => PHPExcel_Style_Alignment::VERTICAL_CENTER,
                            'wrap'       => true],
            'borders'   => ['allborders' => ['style' => PHPExcel_Style_Border::BORDER_THIN,
                                             'color' => ['rgb' => 'CCCCCC']]],
        ];
        $applyStyle('A1:J1', $headerStyle);
        $sheet->getRowDimension(1)->setRowHeight(20);

        $dishHeaderFill = ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => 'D9C09A']];
        $totalRowFill   = ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => 'F2E8D9']];
        $semiFont       = ['color' => ['rgb' => 'CC0000'], 'bold' => false];
        $thinBorder     = ['style' => PHPExcel_Style_Border::BORDER_THIN, 'color' => ['rgb' => 'CCCCCC']];
        $currencyFmt    = '"₹"#,##0.00';
        $numFmt         = '#,##0.####';

        $row = 2;
        $sr  = 1;

        foreach ($products as $prod) {
            // ── Dish header row ───────────────────────────────────────────────
            $sheet->setCellValue("A$row", $sr++);
            $sheet->setCellValue("B$row", strtoupper($prod['name']));
            $sheet->setCellValue("H$row", $prod['total_cost']);
            $sheet->setCellValue("I$row", $prod['price']);
            $margin = round($prod['price'] - $prod['total_cost'], 2);
            $sheet->setCellValue("J$row", $margin);

            $sheet->getStyle("H$row")->getNumberFormat()->setFormatCode($currencyFmt);
            $sheet->getStyle("I$row")->getNumberFormat()->setFormatCode($currencyFmt);
            $sheet->getStyle("J$row")->getNumberFormat()->setFormatCode($currencyFmt);

            $applyStyle("A$row:J$row", [
                'font'      => ['bold' => true, 'size' => 10],
                'fill'      => $dishHeaderFill,
                'alignment' => ['vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER],
                'borders'   => ['allborders' => $thinBorder],
            ]);
            $sheet->getRowDimension($row)->setRowHeight(18);
            $row++;

            // ── Ingredient rows ───────────────────────────────────────────────
            foreach ($prod['ingredients'] as $ing) {
                $isSemi = ($ing['comp_type'] === 'Semifinished');
                $sheet->setCellValue("C$row", $ing['component_name']);
                $sheet->setCellValue("D$row", strtoupper($ing['uom']));
                $sheet->setCellValue("E$row", floatval($ing['req_qty']));
                $sheet->setCellValue("F$row", floatval($ing['unit_cost'] ?? $ing['purchase_price'] ?? 0));
                $sheet->setCellValue("G$row", floatval($ing['per_unit']));
                $sheet->setCellValue("H$row", floatval($ing['line_cost']));

                $sheet->getStyle("F$row")->getNumberFormat()->setFormatCode($currencyFmt);
                $sheet->getStyle("H$row")->getNumberFormat()->setFormatCode($currencyFmt);
                $sheet->getStyle("E$row")->getNumberFormat()->setFormatCode($numFmt);
                $sheet->getStyle("G$row")->getNumberFormat()->setFormatCode($numFmt);

                $ingStyle = [
                    'borders'   => ['allborders' => $thinBorder],
                    'alignment' => ['vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER],
                ];
                if ($isSemi) {
                    $ingStyle['font'] = $semiFont;
                }
                $applyStyle("A$row:J$row", $ingStyle);
                $sheet->getRowDimension($row)->setRowHeight(16);
                $row++;
            }

            // ── Total row ─────────────────────────────────────────────────────
            $sheet->setCellValue("G$row", 'TOTAL');
            $sheet->setCellValue("H$row", $prod['total_cost']);
            $sheet->getStyle("H$row")->getNumberFormat()->setFormatCode($currencyFmt);

            $applyStyle("A$row:J$row", [
                'font'      => ['bold' => true, 'size' => 10],
                'fill'      => $totalRowFill,
                'alignment' => ['horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,
                                'vertical'   => PHPExcel_Style_Alignment::VERTICAL_CENTER],
                'borders'   => ['allborders' => $thinBorder],
            ]);
            $sheet->getStyle("G$row")->getFont()->setBold(true);
            $sheet->getRowDimension($row)->setRowHeight(16);
            $row++;

            // blank spacer
            $row++;
        }

        // freeze header
        $sheet->freezePane('A2');

        // ── Output ────────────────────────────────────────────────────────────
        $filename = 'Recipe_Costing_' . date('Ymd_His') . '.xls';
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($xls, 'Excel5');
        $writer->save('php://output');
        exit;
    }

	// ─────────────────────────────────────────────────────────────────────────
    // EXPORT: Product List
    // ─────────────────────────────────────────────────────────────────────────
    /*
    public function product_list_export()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->autoRender = false;

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $rows = $this->Catalog_product->query(
            "SELECT cp.id, cp.name, cp.cat_name, cp.subcat_name,
                    CASE cp.food_type WHEN 0 THEN 'Not Set' WHEN 1 THEN 'Veg' WHEN 2 THEN 'Non-Veg' WHEN 3 THEN 'Egg' ELSE 'N/A' END AS food_type_label,
                    CASE cp.dish_type WHEN 0 THEN 'Not Set' WHEN 1 THEN 'Food' WHEN 2 THEN 'Beverage' WHEN 3 THEN 'Alcohol' ELSE 'Other' END AS dish_type_label,
                    cp.price, cp.food_cost,
                    CASE WHEN CAST(cp.price AS DECIMAL(12,4)) > 0
                         THEN ROUND(((CAST(cp.price AS DECIMAL(12,4)) - CAST(cp.food_cost AS DECIMAL(12,4))) / CAST(cp.price AS DECIMAL(12,4))) * 100, 2)
                         ELSE 0 END AS margin_pct,
                    cp.unit_name, cp.status, cp.created
             FROM catalog_product cp
             WHERE cp.status = 1
             ORDER BY cp.cat_name, cp.subcat_name, cp.name"
        );

        App::import('Vendor', 'PHPExcel', ['file' => 'PHPExcel' . DS . 'PHPExcel.php']);
        $xls = new PHPExcel();
        $sheet = $xls->getActiveSheet();
        $sheet->setTitle('Products');

        $headers = ['ID','Name','Category','Sub-Category','Food Type','Dish Type','Selling Price','Food Cost','Margin %','Unit','Status','Created'];
        foreach ($headers as $ci => $h) {
            $col = PHPExcel_Cell::stringFromColumnIndex($ci);
            $sheet->setCellValue($col . '1', $h);
            $sheet->getStyle($col . '1')->applyFromArray([
                'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill' => ['type' => PHPExcel_Style_Fill::FILL_SOLID, 'startcolor' => ['rgb' => '4472C4']]
            ]);
            $sheet->getColumnDimension($col)->setWidth(18);
        }

        $rowNum = 2;
        foreach ($rows as $r) {
            // merge: named columns come under ['cp'] alias, computed cols under [0]
            $p = array_merge($r['cp'] ?? $r['catalog_product'] ?? [], $r[0] ?? []);
            if (empty($p)) continue;
            $rowData = [
                $p['id'], $p['name'], $p['cat_name'], $p['subcat_name'],
                $p['food_type_label'], $p['dish_type_label'],
                floatval($p['price']), floatval($p['food_cost']),
                floatval($p['margin_pct']), $p['unit_name'],
                $p['status'] ? 'Active' : 'Inactive', $p['created']
            ];
            foreach ($rowData as $ci => $val) {
                $sheet->setCellValue(PHPExcel_Cell::stringFromColumnIndex($ci) . $rowNum, $val);
            }
            $rowNum++;
        }

        $filename = 'products_' . date('Ymd_His') . '.xls';
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        PHPExcel_IOFactory::createWriter($xls, 'Excel5')->save('php://output');
        exit;
    }
    */
	public function product_list_export()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->autoRender = false;

        // ✅ SAME QUERY AS VIEW
        $rows = $this->Catalog_product->query(
            "SELECT catalog_product.*, 
                    COALESCE(vpc.recipe_cost, 0) as recipe_cost
             FROM catalog_product
             LEFT JOIN v_product_recipe_cost vpc 
                ON vpc.id = catalog_product.id
             WHERE catalog_product.status=1
             ORDER BY catalog_product.id DESC"
        );

        App::import('Vendor', 'PHPExcel', ['file' => 'PHPExcel' . DS . 'PHPExcel.php']);
        $xls = new PHPExcel();
        $sheet = $xls->getActiveSheet();
        $sheet->setTitle('Products');

        // ✅ SAME HEADERS AS UI
        $headers = [
            'ID','Name','Category','SubCategory','Food Type',
            'Recipe Cost','Price','Margin','Cost %',
            'Discountable','Status','Created'
        ];

        foreach ($headers as $ci => $h) {
            $col = PHPExcel_Cell::stringFromColumnIndex($ci);
            $sheet->setCellValue($col . '1', $h);

            $sheet->getStyle($col . '1')->applyFromArray([
                'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill' => [
                    'type' => PHPExcel_Style_Fill::FILL_SOLID,
                    'startcolor' => ['rgb' => '4472C4']
                ]
            ]);

            $sheet->getColumnDimension($col)->setWidth(18);
        }

        // ✅ DATA LOOP (MATCH VIEW EXACTLY)
        $rowNum = 2;

        foreach ($rows as $r) {

            $product = $r['catalog_product'];
            $product['recipe_cost'] = $r[0]['recipe_cost'] ?? 0;

            $price = floatval($product['price']);
            $recipe_cost = floatval($product['recipe_cost']);

            $isValid = ($price > 0 && $recipe_cost > 0);

            // ✅ Margin
            $margin = $isValid ? number_format($price - $recipe_cost, 2) : '-';

            // ✅ Cost %
            $cost_pct = $isValid ? round(($recipe_cost / $price) * 100, 1) : '-';

            // ✅ SAME food type logic as UI
            if ($product['food_type'] == '3') {
                $foodType = 'Alcoholic';
            } elseif ($product['food_type'] == '2') {
                $foodType = 'Non-Alcoholic';
            } elseif ($product['food_type'] == '1') {
                $foodType = 'Non-Veg';
            } else {
                $foodType = 'Veg';
            }

            $rowData = [
                $product['id'],
                $product['name'],
                $product['cat_name'],
                $product['subcat_name'] ?: 'N/A',
                $foodType,
                number_format($recipe_cost, 2),
                $price,
                $margin,
                ($cost_pct !== '-' ? $cost_pct . '%' : '-'),
                (isset($product['is_discountable']) && $product['is_discountable'] == 1 ? 'Yes' : 'No'),
                $product['status'] ? 'Active' : 'Inactive',
                $product['created']
            ];

            foreach ($rowData as $ci => $val) {
                $sheet->setCellValue(
                    PHPExcel_Cell::stringFromColumnIndex($ci) . $rowNum,
                    $val
                );
            }

            $rowNum++;
        }

        // ✅ DOWNLOAD FILE
        $filename = 'products_' . date('Ymd_His') . '.xls';

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');

        PHPExcel_IOFactory::createWriter($xls, 'Excel5')->save('php://output');
        exit;
    }
    
	public function recipe_integrity()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->layout = "users";

        // Get majority recipe UOM for each component (used when creating missing items)
        $majorityUom = [];
        $uomRows = $this->Inventory_linking->query(
            "SELECT component_type, component_id, component_name, component_unit_name,
                    COUNT(*) as cnt
             FROM inventory_linking
             WHERE status=1 AND component_type IN ('Sku','Semifinished')
               AND component_unit_name IS NOT NULL AND component_unit_name != ''
             GROUP BY component_type, component_id, component_name, component_unit_name
             ORDER BY component_type, component_id, cnt DESC"
        );
        foreach ($uomRows as $ur) {
            $r = array_merge($ur['inventory_linking'] ?? $ur[0] ?? [], $ur[0] ?? []);
            $key = ($r['component_type'] ?? '') . '_' . ($r['component_id'] ?? '') . '_' . ($r['component_name'] ?? '');
            if (!isset($majorityUom[$key])) {
                $majorityUom[$key] = $r['component_unit_name'] ?? '';
            }
        }

        $rows = $this->Inventory_linking->query(
            "SELECT
                il.parent_type,
                il.parent_id,
                il.parent_name,
                il.component_type,
                il.component_id,
                il.component_name,
                il.conversion_quantity,
                il.component_unit_name,
                CASE il.component_type
                    WHEN 'Sku' THEN
                        CASE
                            WHEN il.component_id IS NULL OR il.component_id='0' OR il.component_id='' THEN 'MISSING_ID'
                            WHEN sk.id IS NULL THEN 'NOT_IN_TABLE'
                            WHEN COALESCE(sk.consumption_unit_price,0)=0 AND COALESCE(sk.price,0)=0 THEN 'ZERO_PRICE'
                            WHEN sk.name != il.component_name THEN 'NAME_MISMATCH'
                            ELSE 'OK'
                        END
                    WHEN 'Semifinished' THEN
                        CASE
                            WHEN il.component_id IS NULL OR il.component_id='0' OR il.component_id='' THEN 'MISSING_ID'
                            WHEN sf.id IS NULL THEN 'NOT_IN_TABLE'
                            WHEN COALESCE(sf.consumption_unit_price,0)=0 THEN 'ZERO_PRICE'
                            WHEN sf.name != il.component_name THEN 'NAME_MISMATCH'
                            ELSE 'OK'
                        END
                    ELSE 'SKIP'
                END AS status,
                CASE il.component_type WHEN 'Sku' THEN sk.name WHEN 'Semifinished' THEN sf.name END AS actual_name,
                CASE il.component_type WHEN 'Sku' THEN COALESCE(sk.consumption_unit_price,0) WHEN 'Semifinished' THEN COALESCE(sf.consumption_unit_price,0) END AS actual_price,
                CASE il.component_type WHEN 'Sku' THEN sk.unit_name WHEN 'Semifinished' THEN sf.unit_name END AS unit_name
             FROM inventory_linking il
             LEFT JOIN inventory_skus sk ON sk.id = CAST(il.component_id AS UNSIGNED) AND il.component_type='Sku'
             LEFT JOIN inventory_semifinished sf ON sf.id = CAST(il.component_id AS UNSIGNED) AND il.component_type='Semifinished'
             WHERE il.status = 1
               AND il.component_type IN ('Sku','Semifinished')
               AND (
                   il.component_id IS NULL OR il.component_id='0' OR il.component_id=''
                   OR (il.component_type='Sku' AND (sk.id IS NULL OR (COALESCE(sk.consumption_unit_price,0)=0 AND COALESCE(sk.price,0)=0) OR sk.name != il.component_name))
                   OR (il.component_type='Semifinished' AND (sf.id IS NULL OR COALESCE(sf.consumption_unit_price,0)=0 OR sf.name != il.component_name))
               )
             ORDER BY status, il.component_name, il.parent_name"
        );

        $issues = [];
        foreach ($rows as $r) {
            $row = array_merge($r['il'] ?? $r['inventory_linking'] ?? [], $r[0] ?? []);
            $issues[] = $row;
        }

        $summary = ['MISSING_ID' => 0, 'NOT_IN_TABLE' => 0, 'ZERO_PRICE' => 0, 'NAME_MISMATCH' => 0];
        foreach ($issues as $i) {
            $s = $i['status'] ?? 'OK';
            if (isset($summary[$s])) $summary[$s]++;
        }

        $this->set(compact('issues', 'summary', 'majorityUom'));
    }
	
	public function create_missing_ingredient()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->autoRender = false;

        $type        = $this->request->data['type']        ?? '';
        $name        = trim($this->request->data['name']        ?? '');
        $unit_name   = trim($this->request->data['unit_name']   ?? 'Kg');
        $cons_unit   = trim($this->request->data['cons_unit']   ?? 'Gms');
        $cons_factor = floatval($this->request->data['cons_factor'] ?? 1000);

        if (empty($name) || !in_array($type, ['Sku', 'Semifinished'])) {
            $this->Flash->error('Invalid request.');
            return $this->redirect(['action' => 'recipe_integrity']);
        }

        $unitRow = $this->Catalog_unit->find('first', [
            'conditions' => ['Catalog_unit.name' => $unit_name, 'Catalog_unit.status' => 1],
            'fields' => ['id'], 'recursive' => -1
        ]);
        $unit_id = $unitRow ? $unitRow['Catalog_unit']['id'] : 0;

        $consUnitRow = $this->Catalog_unit->find('first', [
            'conditions' => ['Catalog_unit.name' => $cons_unit, 'Catalog_unit.status' => 1],
            'fields' => ['id'], 'recursive' => -1
        ]);
        $cons_unit_id = $consUnitRow ? $consUnitRow['Catalog_unit']['id'] : 0;

        if ($type === 'Sku') {
            $this->loadModel('Inventory_sku');
            $this->Inventory_sku->create();
            $saved = $this->Inventory_sku->save(['Inventory_sku' => [
                'name' => $name, 'unit' => $unit_id, 'unit_name' => $unit_name,
                'consumption_unit_id' => $cons_unit_id, 'consumption_unit_name' => $cons_unit,
                'consumption_factor' => $cons_factor,
                'price' => 0,
                'consumption_unit_price' => 0,
                'status' => 1, 'sync' => 0, 'local_sync' => 0,
            ]]);
            $newId = $saved ? $this->Inventory_sku->getLastInsertID() : null;
        } else {
            $this->Inventory_semifinished->create();
            $saved = $this->Inventory_semifinished->save(['Inventory_semifinished' => [
                'name' => $name, 'unit' => $unit_id, 'unit_name' => $unit_name,
                'consumption_unit_name' => $cons_unit, 'consumption_factor' => $cons_factor,
                'price' => 0, 'consumption_unit_price' => 0,
                'status' => 1, 'sync' => 0, 'local_sync' => 0,
            ]]);
            $newId = $saved ? $this->Inventory_semifinished->getLastInsertID() : null;
        }

        if ($newId) {
            $escapedName = addslashes($name);
            $this->Inventory_linking->query(
                "UPDATE inventory_linking SET component_id='$newId', sync=0, local_sync=0
                 WHERE component_type='$type' AND component_name='$escapedName'
                   AND (component_id IS NULL OR component_id='0' OR component_id='')"
            );
            $this->Flash->success("$type \"$name\" created (ID $newId). Please set the price in the master.");
        } else {
            $this->Flash->error('Could not create the item. Please try again.');
        }

        return $this->redirect(['action' => 'recipe_integrity']);
    }

    
	 public function recalculate_food_costs()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->autoRender = false;

        $this->loadModel('Inventory_sku');
        $this->loadModel('Inventory_semifinished');
        $this->loadModel('Catalog_product');

        // Step 1a: Refresh cross-unit SKUs using latest conversion_factor from catalog_unit_mapping.
        // Uses LEFT JOIN so a conversion_factor change always takes effect even without a new stock-in.
        // Price source priority: (1) latest stock_ledger stockin price, (2) sk.price (manual).
        // e.g. Beer: Keg -> ML -- changing the conversion factor recalculates immediately.
        $this->Inventory_sku->query(
            "UPDATE inventory_skus sk
             LEFT JOIN (
                 SELECT sk2.id AS sku_id,
                     COALESCE(
                         (SELECT CAST(sl.sku_price AS DECIMAL(15,6))
                          FROM stock_ledger sl
                          WHERE sl.sku_id = sk2.id AND sl.record_type = 'stockin'
                            AND CAST(sl.sku_price AS DECIMAL(15,6)) > 0
                          ORDER BY sl.id DESC LIMIT 1),
                         NULLIF(CAST(sk2.price AS DECIMAL(15,6)), 0)
                     )
                     / GREATEST(COALESCE(
                         (SELECT CAST(um.conversion_factor AS DECIMAL(15,6))
                          FROM catalog_unit_mapping um
                          WHERE um.unit_name        = sk2.unit_name
                            AND um.mapped_unit_name = sk2.consumption_unit_name
                            AND um.unit_name       != um.mapped_unit_name
                            AND um.status = 1
                          ORDER BY um.id DESC LIMIT 1),
                         NULLIF(CAST(sk2.consumption_factor AS DECIMAL(15,6)), 0),
                         1
                     ), 1) AS new_price,
                     GREATEST(COALESCE(
                         (SELECT CAST(um.conversion_factor AS DECIMAL(15,6))
                          FROM catalog_unit_mapping um
                          WHERE um.unit_name        = sk2.unit_name
                            AND um.mapped_unit_name = sk2.consumption_unit_name
                            AND um.unit_name       != um.mapped_unit_name
                            AND um.status = 1
                          ORDER BY um.id DESC LIMIT 1),
                         NULLIF(CAST(sk2.consumption_factor AS DECIMAL(15,6)), 0),
                         1
                     ), 1) AS map_cf
                 FROM inventory_skus sk2
                 WHERE sk2.unit_name != sk2.consumption_unit_name
                   AND sk2.status = 1
                   AND sk2.consumption_unit_name IS NOT NULL
                   AND sk2.consumption_unit_name != ''
             ) latest ON latest.sku_id = sk.id
             SET sk.consumption_unit_price = latest.new_price,
                 sk.consumption_factor = latest.map_cf,
                 sk.sync = 0, sk.local_sync = 0
             WHERE sk.status = 1
               AND sk.unit_name != sk.consumption_unit_name
               AND COALESCE(sk.consumption_unit_name, '') != ''
               AND latest.new_price > 0"
        );

        // Step 1b: Refresh same-unit SKUs from latest stock-in price (warehouse or outlet).
        // e.g. Paneer purchased and consumed in Kg — price flows directly from stock_ledger.
        // Placeholder SKUs (price=0) will auto-populate once a PO/stock-in is done.
        $this->Inventory_sku->query(
            "UPDATE inventory_skus sk
             INNER JOIN (
                 SELECT sl.sku_id,
                     CAST(sl.sku_price AS DECIMAL(15,6)) AS new_price
                 FROM stock_ledger sl
                 JOIN inventory_skus sk2 ON sk2.id = sl.sku_id
                 WHERE sl.record_type = 'stockin'
                   AND CAST(sl.sku_price AS DECIMAL(15,6)) > 0
                   AND (sk2.unit_name = sk2.consumption_unit_name
                        OR sk2.consumption_unit_name IS NULL
                        OR sk2.consumption_unit_name = '')
                   AND sl.id = (
                       SELECT MAX(id) FROM stock_ledger sl2
                       WHERE sl2.sku_id = sl.sku_id AND sl2.record_type = 'stockin'
                         AND CAST(sl2.sku_price AS DECIMAL(15,6)) > 0
                   )
             ) latest ON latest.sku_id = sk.id
             SET sk.consumption_unit_price = latest.new_price,
                 sk.sync = 0, sk.local_sync = 0
             WHERE sk.status = 1 AND latest.new_price > 0"
        );

        // Step 2: Refresh SF consumption_unit_price - 3 passes to handle nesting up to 3 levels deep.
        // Pass 1 -> leaf SFs (only SKU ingredients), Pass 2 -> SFs with SF sub-components,
        // Pass 3 -> SFs with SF-of-SF sub-components.
        $sfUpdate = "UPDATE inventory_semifinished isf
             LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = isf.id
             SET isf.consumption_unit_price = COALESCE(vsf.unit_cost, isf.consumption_unit_price),
                 isf.sync = 0,
                 isf.local_sync = 0
             WHERE isf.status = 1
               AND COALESCE(vsf.unit_cost, 0) > 0";
        $this->Inventory_semifinished->query($sfUpdate); // Pass 1: leaf SFs
        $this->Inventory_semifinished->query($sfUpdate); // Pass 2: SFs referencing leaf SFs
        $this->Inventory_semifinished->query($sfUpdate); // Pass 3: third nesting level

        // Step 3: Refresh product food_cost from view (now reflects updated prices)
        $updated = $this->Catalog_product->query(
            "UPDATE catalog_product cp
             LEFT JOIN v_product_recipe_cost vpc ON vpc.id = cp.id
             SET cp.food_cost = COALESCE(vpc.recipe_cost, 0),
                 cp.sync = 0,
                 cp.local_sync = 0
             WHERE cp.status = 1"
        );

        $this->Flash->success(__('Food costs recalculated for all products and semi-finished items.'));
        return $this->redirect(array('action' => 'product_list'));
    }

	
	
    public function package()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller'=>'dashboard', 'action'=>'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product WHERE id = $id");
        $this->set(compact('products'));
    
        $packages = $this->Catalog_package->query("SELECT * FROM catalog_package WHERE main_product_id = $id AND status = 1");
        $this->set(compact('packages'));
    
        if (!empty($_POST['select_semi_name']) && !empty($_POST['pro_price']) && !empty($_POST['pro_quantity'])) {
            $semi_ids = $_POST['select_semi_name'];
            $semi_prices = $_POST['pro_price'];
            $semi_quantities = $_POST['pro_quantity'];
            $semi_units = $_POST['pro_unit'];
            $product_id = $id;
    
            $this->Catalog_package->updateAll(['status' => 0,'sync' => 0,'local_sync' => 0], ['main_product_id' => $product_id]);
    
            $mainProduct = $this->Catalog_product->find('first', [
                'conditions' => ['id' => $product_id],
                'fields' => ['id', 'price', 'name', 'unit', 'unit_name']
            ]);
    
            if (empty($mainProduct)) {
                $this->Flash->error(__('Main product not found.'));
                return $this->redirect(['action' => 'product_list']);
            }
    
            $main_price = $mainProduct['Catalog_product']['price'];
            $main_name = $mainProduct['Catalog_product']['name'];
            $main_unit = $mainProduct['Catalog_product']['unit'];
            $main_unit_name = $mainProduct['Catalog_product']['unit_name'];
    
            foreach ($semi_ids as $i => $link_id) {
                $link_price = $semi_prices[$i];
                $link_qty = $semi_quantities[$i];
    
                if (empty($link_id) || $link_qty <= 0) continue;
    
                $linkProduct = $this->Catalog_product->find('first', [
                    'conditions' => ['id' => $link_id],
                    'fields' => ['id', 'name', 'unit', 'unit_name']
                ]);
    
                if (!empty($linkProduct)) {
                    $data['Catalog_package'] = [
                        'main_product_id' => $product_id,
                        'main_product_name' => $main_name,
                        'main_product_unit_id' => $main_unit,
                        'main_product_unit_name' => $main_unit_name,
                        'main_product_price' => $main_price,
                        'link_product_id' => $link_id,
                        'link_product_name' => $linkProduct['Catalog_product']['name'],
                        'link_product_unit_id' => $linkProduct['Catalog_product']['unit'],
                        'link_product_unit_name' => $linkProduct['Catalog_product']['unit_name'],
                        'link_product_price' => $link_price,
                        'link_quantity' => $link_qty,
                        'status' => 1,
                        'sync' => 0,
                        'local_sync' => 0
                    ];
    
                    $this->Catalog_package->create();
                    if (!$this->Catalog_package->save($data)) {
                        $this->Flash->error(__('Failed to save package item.'));
                    }
                }
            }
    
            $this->Catalog_product->updateAll(['package' => 1,'sync' => 0,'local_sync' => 0], ['id' => $product_id]);
    
            $this->Flash->success(__('Package saved successfully.'));
            return $this->redirect(['action' => 'product_list']);
        }
    }

    public function fetch_semifinished_options() {
        $this->autoRender = false; // Disable view rendering
        $semifinishedd=array();
        $semifinisheds = $this->Inventory_semifinished->find('all', [
            'conditions' => ['status' => 1],
            'order' => ['Inventory_semifinished.name' => 'ASC']
        ]);
        foreach($semifinisheds as $semifinished){
            $semifinishedd[]=$semifinished['Inventory_semifinished'];
        }
        $responseArray = array('response_code' => 1, 'data' => $semifinishedd);
        echo json_encode($responseArray);

    }
    
    public function fetch_sku_options() {
        $this->autoRender = false; // Disable view rendering
        $skuss=array();
        $skus = $this->Inventory_sku->find('all', [
            'conditions' => ['status' => 1, 'item_type' => 1],
            'order' => ['Inventory_sku.name' => 'ASC']
        ]);

        foreach($skus as $sku){
            $skuss[]=$sku['Inventory_sku'];
        }
        $responseArray = array('response_code' => 1, 'data' => $skuss);
        echo json_encode($responseArray);

    }
    
    public function bill_printpdf() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "login";
        
        $id=  $_GET['id'];
        
        $transactions = $this->Order_transaction->query("
            SELECT 
                order_transactions.*, 
                locations.*,
                users.name as cashiername
            FROM 
                order_transactions
            LEFT JOIN 
                users ON users.id = order_transactions.cashier_id
            LEFT JOIN 
                locations ON locations.id = users.location_id
            WHERE 
                order_transactions.id = ".$id." and order_transactions.status!=0
        ");
        
        $reference_id=$transactions[0]['order_transactions']['reference_id'];
        $storeId=$transactions[0]['order_transactions']['store_id'];
        $cashier_id=$transactions[0]['order_transactions']['cashier_id'];
        $orderno=$transactions[0]['order_transactions']['orderno'];
        $discount=$transactions[0]['order_transactions']['discount'];
        $servicecharge=$transactions[0]['order_transactions']['servicecharge'];
        $delivery_charge=$transactions[0]['order_transactions']['delivery_charge'];
        $packing_charge=$transactions[0]['order_transactions']['packing_charge'];
        $amount=$transactions[0]['order_transactions']['amount'];
        $created=$transactions[0]['order_transactions']['created'];
        $table_number=$transactions[0]['order_transactions']['table_number'];
        $pax=$transactions[0]['order_transactions']['pax'];
        $price=$transactions[0]['order_transactions']['price'];
        $today= date('Y-m-d H:i:s');
        
        $name=$transactions[0]['locations']['name'];
        $print_line1=$transactions[0]['locations']['print_line1'];
        $print_line2=$transactions[0]['locations']['print_line2'];
        $print_line3=$transactions[0]['locations']['print_line3'];
        $print_line4=$transactions[0]['locations']['print_line4'];
        $print_line5=$transactions[0]['locations']['print_line5'];
        $print_line6=$transactions[0]['locations']['print_line6'];
        $print_line7=$transactions[0]['locations']['print_line7'];
        $print_line8=$transactions[0]['locations']['print_line8'];
        $print_line9=$transactions[0]['locations']['print_line9'];
        $print_line10=$transactions[0]['locations']['print_line10'];
        $footer_msg=$transactions[0]['locations']['footer_msg'];
        $currency_symbol=$transactions[0]['locations']['currency_symbol'];
        $cashiername=$transactions[0]['users']['cashiername'];
        
        $orderss = $this->Order_orderhistory->query("SELECT id,product_name,SUM(quantity) as quantity,sum(total_price) as total_price FROM `order_orderhistories` WHERE reference_id='$reference_id' and store_id = '$storeId' and status!=0 group BY product_id");
        $taxes = $this->Order_tax->query("SELECT tax_id,tax_name,tax_percentage,sum(tax_value) as tax_value FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 GROUP by tax_id");
        $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and discount_percentage!=0 and status!=0 limit 1");
        if(!empty($discper))
        {
            $discount_percentage=$discper[0]['order_tax']['discount_percentage'];
        }
        if(!isset($discount_percentage)){
            $discount_percentage="0";
        }
        
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        $mode=   $payments[0]['Order_payment']['type_value'];
                    
        $this->set(compact('pax','currency_symbol','delivery_charge','packing_charge','mode','price','table_number','cashiername','servicecharge','amount','today','created','name','print_line1','print_line2','print_line3','print_line4','print_line5','print_line6','print_line7','print_line8','print_line9','print_line10','orderno','orderss','taxes','footer_msg','discount_percentage','discount'));
        
    }
    
    
    public function internal_indent_list()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        // --- Default date range: last 1 month
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate   = date('m/d/Y');
        $startdate = date('Y-m-d', strtotime('-1 month'));
        $enddate   = date('Y-m-d');

        // --- Handle date range from form
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            if (strpos($daterange, '-') !== false) {
                list($startRaw, $endRaw) = explode(" - ", $daterange);
                $startDate = trim($startRaw);
                $endDate   = trim($endRaw);
                $startdate = date('Y-m-d', strtotime($startDate));
                $enddate   = date('Y-m-d', strtotime($endDate));
            }
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // --- Session values
        $authUser  = $this->Session->read('Auth.User');
        $userRole  = $authUser['role'] ?? '';
        $locationIds = $authUser['location_ids'] ?? '';

        // --- Build conditions for store dropdown
        $conditions2 = ['status' => 1];

        if ($userRole !== 'admin' && !empty($locationIds)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($locationIds) ? $locationIds : explode(',', $locationIds)],
                'ids.{n}'
            );
            $conditions2['id IN'] = array_map('trim', $userLocationIds);
        }

        $stores = $this->Location->find('all', [
            'conditions' => $conditions2
        ]);
        $this->set(compact('stores'));

        // --- Build query conditions for internal indent
        $indentConditions = [
            'status' => 1,
            "created >=" => $startDatetime,
            "created <=" => $endDatetime,
        ];

        // Restrict by role
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $indentConditions['location_id IN'] = $conditions2['id IN'];
        }

        // Override with cashier search (applies to everyone)
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $indentConditions['location_id'] = $cashierId;
        }

        // --- Fetch internal indent records
        $users = $this->Inventory_internal_indent->find('all', [
            'conditions' => $indentConditions,
            'order' => ['id' => 'DESC']
        ]);

        // --- Pass variables to view
        $this->set(compact('users'));
        
        $openindentConditions = [
            'status' => 1,
            'is_completed' => 0
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $openindentConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $openindentConditions['location_id'] = $cashierId;
        }
        $open_indents = $this->Inventory_internal_indent->find('count', [
            'conditions' => $openindentConditions
        ]);
        $this->set(compact('open_indents'));
        
        $closedindentConditions = [
            'status' => 1,
            'is_completed' => 1
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $closedindentConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $closedindentConditions['location_id'] = $cashierId;
        }
        $closed_indents = $this->Inventory_internal_indent->find('count', [
            'conditions' => $closedindentConditions
        ]);
        
        $this->set(compact('open_indents'));
        $this->set(compact('closed_indents'));
        
        $this->set('startdate', $startDate . ' - ' . $endDate);
    }

    public function create_internal_indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        if ($this->Session->read('Auth.User.role') == 'admin') {
            $locations = $this->Location->find('all', ['conditions' => ['status' => 1]]);
        } else {
            
            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;
            
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
            
            $locationCondition = ['status' => 1,'type' => 'dc'];
            
            $locations = $this->Location->find('all', [
                'conditions' => [
                    $locationCondition
                ]
            ]);
            
        }
        
    
        $this->set(compact('locations'));
    
        // $users = $this->Inventory_sku->find('all', [
        //     'conditions' => ['Inventory_sku.status' => 1],
        //     'order' => ['Inventory_sku.name ASC']
        // ]);
        $users = $this->Inventory_sku->find('all', [
            'fields' => [
                'Inventory_sku.*',
                'COALESCE(SUM(Inventory_sku_tax.tax_percentage),0) AS total_tax'
            ],
            'joins' => [
                [
                    'table' => 'inventory_sku_tax',
                    'alias' => 'Inventory_sku_tax',
                    'type' => 'LEFT',
                    'conditions' => [
                        'Inventory_sku_tax.product_id = Inventory_sku.id',
                        'Inventory_sku_tax.status' => 1
                    ]
                ]
            ],
            'conditions' => [
                'Inventory_sku.status' => 1
            ],
            'group' => ['Inventory_sku.id'],
            'order' => ['Inventory_sku.name ASC']
        ]);
        $this->set(compact('users'));
    }

    public function add_internal_indent() 
    {
        $this->autoRender = false;
    
        if (!$this->Session->check('Auth.User.id')) {
            echo json_encode(['response_code' => 0, 'data' => 'User session expired.']);
            return;
        }
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData']) && isset($_POST['location_id'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $location_id = (int)$_POST['location_id'];
    
            // Validate location
            $location = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location_id],
                'fields' => ['id', 'name'],
                'recursive' => -1
            ]);
    
            if (empty($location)) {
                echo json_encode(['response_code' => 0, 'data' => 'Invalid location selected.']);
                return;
            }
    
            // Generate unique indent_id
            do {
                // $txnid = '';
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
    
                $existing = $this->Inventory_internal_indent_items->find('first', [
                    'conditions' => ['indent_id' => $txnid],
                    'recursive' => -1
                ]);
            } while ($existing);
    
            $amount = 0;
            $itemsSaved = true;
    
            foreach ($checkeddatas as $item) {
                $skuid = $item['id'];
                $price = $item['price'];
                $quantity = $item['sku_quantity'];
                
                $product_taxes=$this->Inventory_sku_tax->query("select SUM(tax_percentage) as total_tax from inventory_sku_tax where product_id='$skuid'  AND status = 1");
                $total_tax=round($product_taxes['0']['0']['total_tax'],2);
                $tax_value = round(($price*$quantity) * ($total_tax / 100),2);
                $skuamount=round(($price*$quantity) + $tax_value,2);
                
                $skuData = [
                    'indent_id' => $txnid,
                    'sku_id' => $skuid,
                    'sku_name' => $item['sku_name'],
                    'sku_brand' => $item['sku_brand'],
                    'sku_unit' => $item['unit_id'],
                    'sku_unit_name' => $item['unit_name'],
                    'sku_price' => $price,
                    'sku_quantity' => $quantity,
                    'sku_total_tax_percentage' => $total_tax,
                    'sku_total_tax_value' => $tax_value,
                    'sku_amount' => $skuamount,
                    'sync' => 0,
                    'local_sync' => 0
                ];
    
                $this->Inventory_internal_indent_items->create(); // ensure new row
                if (!$this->Inventory_internal_indent_items->save($skuData)) {
                    $itemsSaved = false;
                    break;
                }
    
                $amount += ($skuamount);
            }
    
            if ($itemsSaved) {
                $indentData = [
                    'indent_id' => $txnid,
                    'created_by' => $id,
                    'created_by_name' => $name,
                    'total_amount' => $amount,
                    'location_id' => $location['Location']['id'],
                    'location_name' => $location['Location']['name'],
                    'sync' => 0,
                    'local_sync' => 0
                ];
    
                $this->Inventory_internal_indent->create();
                if ($this->Inventory_internal_indent->save($indentData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'saved']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Failed to save indent master data.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Failed to save one or more items.']);
            }
        } else {
            echo json_encode(['response_code' => 0, 'data' => 'Invalid request. Missing data.']);
        }
    }

    public function view_internal_indent()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Inventory_internal_indent->query("SELECT * FROM inventory_internal_indent where indent_id=$id and status=1");
        $this->set(compact('indents'));
        
        $items = $this->Inventory_internal_indent_items->query("SELECT * FROM inventory_internal_indent_items where indent_id=$id and status=1");
        
        $this->set(compact('items'));
        
        
    }
    
    public function edit_internal_indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $user_id = $this->Session->read('Auth.User.id');
        $role = $this->Session->read('Auth.User.role');
        $user_location = $this->Session->read('Auth.User.location_id');
    
        // Location dropdown data
        if ($role == 'admin') {
            $locations = $this->Location->find('list', ['conditions' => ['status' => 1]]);
        } else {
            $locations = $this->Location->find('list', [
                'conditions' => ['status' => 1, 'id' => $user_location]
            ]);
        }
    
        // Fetch indent data
        // $user = "SELECT *,
        //     (SELECT sku_quantity FROM inventory_internal_indent_items 
        //      WHERE indent_id='$id' AND sku_id=inventory_skus.id and status=1) as quantity 
        //     FROM inventory_skus 
        //     WHERE inventory_skus.status=1 
        //     ORDER BY inventory_skus.name ASC";
        $user = "
            SELECT *,
                (
                    SELECT sku_quantity 
                    FROM inventory_internal_indent_items 
                    WHERE indent_id='$id' 
                    AND sku_id = inventory_skus.id 
                    AND status = 1
                ) as quantity,
            
                (
                    SELECT COALESCE(SUM(tax_percentage),0)
                    FROM inventory_sku_tax
                    WHERE product_id = inventory_skus.id
                    AND status = 1
                ) as total_tax
            
            FROM inventory_skus
            WHERE inventory_skus.status = 1
            ORDER BY inventory_skus.name ASC
        ";
        $users = $this->Inventory_sku->query($user);
    
        // Fetch existing indent record
        $indentData = $this->Inventory_internal_indent->find('first', [
            'conditions' => ['indent_id' => $id,'status' => 1],
            'recursive' => -1
        ]);
    
        $selected_location_id = $indentData['Inventory_internal_indent']['location_id'];
    
        $this->set(compact('users', 'id', 'locations', 'selected_location_id'));
    }

    public function update_internal_indent() 
    {
        $this->autoRender = false;
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentid = $_POST['indent_id'];
            $location_id = isset($_POST['location_id']) ? $_POST['location_id'] : null;
            $location_name = '';
            // C7: block edit if PO exists for this indent
            $indentLock = $this->Inventory_internal_indent->field('po_locked', ['indent_id' => $indentid]);
            if (!empty($indentLock)) {
                echo json_encode(['response_code' => 0, 'data' => 'This indent is locked: a PO already exists. Cancel the PO first.']);
                return;
            }
    
            // Optional: fetch location name if not passed from frontend
            if (!empty($location_id)) {
                $loc = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $location_id],
                    'fields' => ['Location.name'],
                    'recursive' => -1
                ]);
                $location_name = isset($loc['Location']['name']) ? $loc['Location']['name'] : '';
            }
    
            // Delete existing indent and items
            $this->Inventory_internal_indent_items->query("UPDATE inventory_internal_indent_items SET status=0,sync=0,local_sync=0 WHERE indent_id = " . (int)$indentid);
            $this->Inventory_internal_indent->query("UPDATE inventory_internal_indent SET status=0,sync=0,local_sync=0 WHERE indent_id = " . (int)$indentid);
    
            $amount = 0;
            $chk = false;
    
            foreach ($checkeddatas as $checkeddata) {
                $skuid = $checkeddata['id'];
                $price = $checkeddata['price'];
                $sku_name = $checkeddata['sku_name'];
                $sku_brand = $checkeddata['sku_brand'];
                $unit_name = $checkeddata['unit_name'];
                $unit_id = $checkeddata['unit_id'];
                $quantity = $checkeddata['sku_quantity'];
                $is_completed = $checkeddata['is_completed'];
                $completed_quantity = $checkeddata['completed_quantity'] ?? 0;
                
                $product_taxes=$this->Inventory_sku_tax->query("select SUM(tax_percentage) as total_tax from inventory_sku_tax where product_id='$skuid' and status=1");
                $total_tax=round($product_taxes['0']['0']['total_tax'],2);
                $tax_value = round(($price*$quantity) * ($total_tax / 100),2);
                $skuamount=round(($price*$quantity) + $tax_value,2);
                
                if (!empty($quantity)) {
                    if($completed_quantity>=$quantity){
                        $is_completed=1;
                    }else{
                        $is_completed=0;
                    }

                    $itemData = array(
                        'indent_id' => $indentid,
                        'sku_id' => $skuid,
                        'sku_name' => $sku_name,
                        'sku_brand' => $sku_brand,
                        'sku_unit' => $unit_id,
                        'sku_unit_name' => $unit_name,
                        'sku_price' => $price,
                        'sku_quantity' => $quantity,
                        'sku_total_tax_percentage' => $total_tax,
                        'sku_total_tax_value' => $tax_value,
                        'sku_amount' => $skuamount,
                        'is_completed' => $is_completed,
                        'completed_quantity' => $completed_quantity,
                        'sync'      =>0,
                        'local_sync' =>0
                    );
    
                    if ($this->Inventory_internal_indent_items->saveAll($itemData)) {
                        $chk = true;
                    } else {
                        $chk = false;
                        $this->Flash->error(__('Internal indent could not be updated. Please, try again.'));
                    }
    
                    // $productamount = $quantity * $price;
                    // $amount += $productamount;
                    $amount += ($skuamount);
                }
            }
            
            if ($chk) {
                                
                $checkindent = "
                    SELECT id
                    FROM inventory_internal_indent_items
                    WHERE status = 1
                      AND is_completed = 0
                      AND indent_id = " . (int)$indentid;
                
                $checkindentstatus = $this->Inventory_internal_indent_items->query($checkindent);
                
                if (!empty($checkindentstatus)) {
                    // 👉 At least one pending item exists
                    $indentcomplete = 0;
                } else {
                    // 👉 All items completed
                    $indentcomplete = 1;
                }


                $indentData = array(
                    'indent_id' => $indentid,
                    'created_by' => $id,
                    'created_by_name' => $name,
                    'location_id' => $location_id,
                    'location_name' => $location_name,
                    'total_amount' => $amount,
                    'is_updated' => 1,
                    'is_completed' => $indentcomplete,
                    'status'    => 1,  // T27-fix: re-activate indent after update
                    'sync'      =>0,
                    'local_sync' =>0
                );
    
                if ($this->Inventory_internal_indent->saveAll($indentData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'Updated']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Internal indent could not be updated. Please, try again.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Internal indent items could not be updated. Please, try again.']);
            }
        }
    }

    public function po_list()
    {
        // Redirect if not authenticated
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $locationIds = $authUser['location_ids'] ?? '';

        // --- Default date range (last 1 month)
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate   = date('m/d/Y');
        $startDateFormatted = date('Y-m-d', strtotime('-1 month'));
        $endDateFormatted   = date('Y-m-d');

        // --- Handle custom date range from form
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            if (strpos($daterange, '-') !== false) {
                list($startRaw, $endRaw) = explode(" - ", $daterange);
                $startDate = trim($startRaw);
                $endDate   = trim($endRaw);
                $startDateFormatted = date('Y-m-d', strtotime($startDate));
                $endDateFormatted   = date('Y-m-d', strtotime($endDate));
            }
        }

        // --- Build store conditions
        $conditions2 = ['status' => 1];

        if ($userRole !== 'admin' && !empty($locationIds)) {
            // Normalize location IDs to array
            $userLocationIds = Hash::extract(
                ['ids' => is_array($locationIds) ? $locationIds : explode(',', $locationIds)],
                'ids.{n}'
            );
            $conditions2['id IN'] = array_map('trim', $userLocationIds);
        }

        // --- Fetch stores
        $stores = $this->Location->find('all', [
            'conditions' => $conditions2
        ]);
        
        $startDatetime = $startDateFormatted . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($endDateFormatted . ' +1 day')) . ' ' . shiftend;

        // --- Build purchase order conditions
        $poConditions = [
            "status !=" => 0,
            "direct_purchase" => 0,
            "created >=" => $startDatetime,
            "created <=" => $endDatetime,
        ];

        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $poConditions['location_id IN'] = $conditions2['id IN'];
        }

        // --- Apply cashier search (overrides for all roles)
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $poConditions['location_id'] = $cashierId;
        }

        // --- Fetch purchase orders
        $purchaseOrders = $this->Inventory_purchase_order->find('all', [
            'conditions' => $poConditions,
            'order' => ['id' => 'DESC']
        ]);
        
        
        // $dbo = $this->Inventory_purchase_order->getDataSource();
        // $logs = $dbo->getLog();
        // $lastQuery = end($logs['log']);
        // debug($lastQuery);die;

        // --- Pass data to view
        $this->set(compact('stores', 'purchaseOrders'));
        
        $submittedpoConditions = [
            "status" => 1,
            "direct_purchase" => 0
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $submittedpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $submittedpoConditions['location_id'] = $cashierId;
        }
        $submittedpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $submittedpoConditions
        ]);
        
        $approvedpoConditions = [
            "status" => 2,
            "direct_purchase" => 0
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $approvedpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $approvedpoConditions['location_id'] = $cashierId;
        }
        $approvedpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $approvedpoConditions
        ]);
        
        $processedpoConditions = [
            "status" => 3,
            "direct_purchase" => 0
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $processedpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $processedpoConditions['location_id'] = $cashierId;
        }
        $processedpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $processedpoConditions
        ]);
        
        $stockedinpoConditions = [
            "status" => 4,
            "direct_purchase" => 0
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $stockedinpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $stockedinpoConditions['location_id'] = $cashierId;
        }
        $stockedinpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $stockedinpoConditions
        ]);
        $this->set(compact( 'submittedpo','approvedpo','processedpo','stockedinpo'));
        

        $this->set('startdate', $startDate . ' - ' . $endDate);
    }

    public function create_po()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? 0;
        $id = $authUser['id'];
        $name = $authUser['name'];
        
        // Vendors
        $vendoroptions = $this->Inventory_vendor->find('list', [
            'conditions' => ['Inventory_vendor.status' => 1],
            'fields' => ['id', 'company'],
            'order' => ['name' => 'ASC'],
            'recursive' => -1
        ]);
    
        // Locations
        $locationOptions = $this->Location->find('list', [
            'conditions' => ['status' => 1] + ($userRole !== 'admin' ? ['id' => $userLocationId] : []),
            'fields' => ['id', 'name'],
            'order' => ['name' => 'ASC'],
            'recursive' => -1
        ]);
    
        $this->set(compact('vendoroptions', 'locationOptions'));
    
        // Handle form submission
        if ($this->request->is(['post', 'put'])) {
            $data = $this->request->data['User'];
            $today = date('Y-m-d H:i:s');
            
            $locationId = (int) ($data['location'] ?? 0);
            $locationSave = $this->Auth->user('id'); // logged in user
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$locationId)));
            $locationname=$locationdetail['Location']['name'];
            
            $location_type=$locationdetail['Location']['type'];

            $indentId = (int) $data['indent'];
            $vendorId = (int) $data['vendor'];
            $prices = $this->request->data('prices') ?? [];
            $quantities = $this->request->data('quantity') ?? [];
            $vendor = $this->Inventory_vendor->find('first', [
                'conditions' => ['Inventory_vendor.id' => $vendorId],
                'recursive' => -1
            ]);
        
            $charge = $data['charge'] ?? 0;
            $po_date = $_POST['po_date'];
            
            if (empty($vendor)) {
                $this->Flash->error(__('Invalid vendor selected.'));
                return;
            }
            $approval_amount=approval_amount;
            
            if($vendor['Inventory_vendor']['po_approval_required']){
                $postatus = 1;
            }else{
                $postatus = 2;
            }
            
            do {
                $poId = str_pad(mt_rand(1, 9999999999), 10, '0', STR_PAD_LEFT);
            } while ($this->Inventory_purchase_order->hasAny(['p_o_id' => $poId]));
        
            $totalAmount = 0;
            $totaldiscount=0;
            
            foreach ($quantities as $skuId => $qty) {
                $qty = (float) $qty;
                if ($qty <= 0) continue;
        
                $price = isset($prices[$skuId]) ? (float) $prices[$skuId] : 0;
        
                $sku = $this->Inventory_sku->find('first', [
                    'conditions' => ['Inventory_sku.id' => $skuId],
                    'recursive' => -1
                ]);
                
                if (empty($sku)) continue;
                
                $product_taxes=$this->Inventory_sku_tax->query("select SUM(tax_percentage) as total_tax from inventory_sku_tax where product_id='$skuId' and status=1");
                $total_tax=round($product_taxes['0']['0']['total_tax'],2);
                
                if($postatus==2){
                    $approved_quantity=$qty;
                    $approved_total_tax_value=$total_tax;
                    $approved_amount=$skuamount;
                }else{
                    $approved_quantity=0;
                    $approved_total_tax_value=0;
                    $approved_amount=0;
                }

                $baseAmount = $price * $qty;

                $itemDiscountType = $this->request->data['discount_type'][$skuId] ?? 'flat';

                // Changed 'discount' to 'sku_discount' to match the frontend form data
                $discountInput = isset($this->request->data['sku_discount'][$skuId]) 
                    ? (float)$this->request->data['sku_discount'][$skuId] 
                    : 0;

                /* ------------------------------
                DISCOUNT CALCULATION
                ------------------------------ */

                if ($itemDiscountType === 'percentage') {

                    if ($discountInput > 100) {
                        $discountInput = 100;
                    }

                    $itemDiscountValue = round(($baseAmount * $discountInput) / 100, 2);

                } else {

                    if ($discountInput > $baseAmount) {
                        $discountInput = $baseAmount;
                    }

                    $itemDiscountValue = $discountInput;
                }

                $amountAfterDiscount = $baseAmount - $itemDiscountValue;

                $tax_value = round($amountAfterDiscount * ($total_tax / 100), 2);

                $skuamountFinal = round($amountAfterDiscount + $tax_value, 2);

                $itemData = [
                    'Inventory_purchase_order_item' => [
                        'p_o_id' => $poId,
                        'internal_indent_id' => $indentId,
                        'sku_id' => $skuId,
                        'sku_name' => $sku['Inventory_sku']['name'],
                        'sku_unit' => $sku['Inventory_sku']['unit'],
                        'sku_unit_name' => $sku['Inventory_sku']['unit_name'],
                        'sku_price' => $price,
                        'sku_quantity' => $qty,
                        'sku_total_tax_percentage' => $total_tax,
                        'sku_total_tax_value' => $tax_value,
                        'sku_discount_type' => $itemDiscountType,
                        'sku_discount' => $discountInput,          // original input (5 or 50)
                        'sku_discount_value' => $itemDiscountValue, // calculated value
                        'sku_amount' => $skuamountFinal,
                        'approved_quantity' => $approved_quantity,
                        'approved_total_tax_value' => $approved_total_tax_value,
                        'approved_amount' => ($postatus == 2) ? $skuamountFinal : 0,
                        'status' => $postatus,
                        'sync'      =>0,
                        'local_sync' =>0
                    ]
                ];
            
                if (!$this->Inventory_purchase_order_item->saveAll($itemData)) {
                    $this->Flash->error(__('Failed to save PO item.'));
                    return;
                }

                $totalAmount += $skuamountFinal;
                $totaldiscount += $itemDiscountValue;
            
            }
            
            if($totalAmount>$approval_amount){
                $postatus=1;
            }
            
            if($postatus==2){
                $approved_by_id=$id;
                $approved_by_name=$name;
                $approved_on=$today;
                $approved_amount=$totalAmount+$charge;
            }else{
                $approved_by_id=0;
                $approved_by_name='';
                $approved_on=NULL;
                $approved_amount=0;
            }
            
            $poData = [
                'Inventory_purchase_order' => [
                    'p_o_id' => $poId,
                    'vendor_id' => $vendorId,
                    'vendor_name' => $vendor['Inventory_vendor']['company'],
                    'internal_indent_id' => $indentId,
                    'location_id' => $locationId,
                    'location_name' => $locationname,
                    'location_type' => $location_type,
                    'charge' => $charge,
                    'total_amount' => $totalAmount+$charge,
                    'status' => $postatus,
                    'approved_by_id' => $approved_by_id,
                    'approved_by_name' => "$approved_by_name", // string needs quoting
                    'approved_on' => $approved_on,      // string needs quoting
                    'approved_amount' => $approved_amount,
                    'sync'      =>0,
                    'local_sync' =>0,
                    'discount_value' => $totaldiscount,
                    'po_date' => $po_date
                    
                ]
            ];
            
            $this->Inventory_purchase_order_item->query("UPDATE inventory_purchase_order_items set approved_quantity=0,approved_total_tax_value=0,approved_amount=0,status=$postatus,sync=0,local_sync=0 WHERE status!=0 and p_o_id =". $poId);
           
            if ($this->Inventory_purchase_order->saveAll($poData)) {
                
                                
                // ================= INTERNAL INDENT ITEM & INDENT UPDATE =================
                
                $indentItems = $this->Inventory_internal_indent_items->find('all', [
                    'conditions' => [
                        'Inventory_internal_indent_items.indent_id' => $indentId,
                        'Inventory_internal_indent_items.status' => 1
                    ],
                    'recursive' => -1
                ]);
                $allItemsCompleted = true;
                
                foreach ($indentItems as $item) {
                    $itemId    = $item['Inventory_internal_indent_items']['Id'];
                    $skuId     = $item['Inventory_internal_indent_items']['sku_id'];
                    $indentQty = (float)$item['Inventory_internal_indent_items']['sku_quantity'];
                
                    // Total PO quantity for this SKU under this indent
                    $poQtyData = $this->Inventory_purchase_order_item->find('first', [
                        'conditions' => [
                            'Inventory_purchase_order_item.internal_indent_id' => $indentId,
                            'Inventory_purchase_order_item.sku_id' => $skuId,
                            'Inventory_purchase_order_item.status !=' => 0
                        ],
                        'fields' => [
                            'SUM(Inventory_purchase_order_item.sku_quantity) as total_qty'
                        ],
                        'recursive' => -1
                    ]);
                
                    $totalPoQty = (float)($poQtyData[0]['total_qty'] ?? 0);
                
                    // Prevent over-completion
                    if ($totalPoQty > $indentQty) {
                        $totalPoQty = $indentQty;
                    }
                
                    // Update indent item
                    $this->Inventory_internal_indent_items->updateAll(
                        [
                            'Inventory_internal_indent_items.completed_quantity' => $totalPoQty,
                            'Inventory_internal_indent_items.is_completed' =>
                                ($totalPoQty >= $indentQty) ? 1 : 0
                        ],
                        [
                            'Inventory_internal_indent_items.id' => $itemId,
                            'Inventory_internal_indent_items.status' => 1
                        ]
                    );
                
                    // If any item not completed → indent not completed
                    if ($totalPoQty < $indentQty) {
                        $allItemsCompleted = false;
                    }
                }
                
                // ================= INTERNAL INDENT UPDATE =================
                
                if ($allItemsCompleted) {
                    $this->Inventory_internal_indent->updateAll(
                        [
                            'Inventory_internal_indent.is_completed' => 1, // or -1 if your system uses that
                            'Inventory_internal_indent.modified' =>
                                "'" . date('Y-m-d H:i:s') . "'"
                        ],
                        [
                            'Inventory_internal_indent.indent_id' => $indentId,
                            'Inventory_internal_indent.status' => 1
                        ]
                    );
                }


                // C7: lock the indent so it cannot be edited while an active PO exists
                $this->Inventory_indent->query(
                    "UPDATE inventory_internal_indent SET po_locked=1, sync=0, local_sync=0 WHERE indent_id=" . (int)$indentId
                );
                
                $this->Flash->success(__('PO has been successfully created.'));
                return $this->redirect(['action' => 'po_list']);
            } else {
                $this->Flash->error(__('Failed to save PO. Please try again.'));
            }
        }
    }
    
    public function fetch_indents_by_location()
    {
        $this->autoRender = false; 
        $this->layout = null;
    
        if ($this->request->is('ajax')) {
            $locationId = (int)$this->request->data('location_id');
            $this->loadModel('Inventory_internal_indent');
    
            $indents = $this->Inventory_internal_indent->find('list', [
                'conditions' => [
                    'location_id' => $locationId,
                    'status' => 1,
                    'is_completed' => 0,
                    'po_locked' => 0
                ],
                'fields' => ['indent_id', 'indent_id'], // Or add name if needed
                'order' => ['id' => 'DESC'],
                'recursive' => -1
            ]);
    
            echo json_encode($indents);
        }
    }
        
    public function fetch_vendors_by_indent()
    {
        $this->autoRender = false;
        $this->layout = null;
    
        $indentId = (int)$this->request->data('indent_id');
        $location_id = $this->request->data('location_id');
    
        if (!$indentId) {
            echo json_encode([]);
            return;
        }
    
        // 1️⃣ Get SKUs from indent
        $skus = $this->Inventory_internal_indent_items->find('list', [
            'conditions' => [
                'indent_id' => $indentId,
                'status' => 1,
                'is_completed' => 0
            ],
            'fields' => ['sku_id', 'sku_id'],
            'recursive' => -1
        ]);
    
        if (empty($skus)) {
            echo json_encode([]);
            return;
        }
        
        $locationdetail = $this->Location->find('first', [
            'conditions' => ['Location.id' => $location_id]
        ]);
        if($locationdetail['Location']['type']=='Outlet'){
        // 2️⃣ Get vendors serving these SKUs
            $vendors = $this->Inventory_vendor->query("
                SELECT DISTINCT v.id, v.company
                FROM inventory_vendors v
                INNER JOIN inventory_vendor_sku_served vs 
                    ON vs.vendor_id = v.id
                INNER JOIN inventory_vendor_service_areas vsa 
                    ON vsa.vendor_id = v.id
                WHERE 
                    vs.skus_id IN (" . implode(',', array_keys($skus)) . ")
                    and vsa.area_id = $location_id
                    AND vs.status = 1
                    AND v.status = 1
                ORDER BY v.company ASC
            ");
        }else{
            $vendors = $this->Inventory_vendor->query("
                SELECT DISTINCT v.id, v.company
                FROM inventory_vendors v
                INNER JOIN inventory_vendor_sku_served vs 
                    ON vs.vendor_id = v.id
                WHERE 
                    vs.skus_id IN (" . implode(',', array_keys($skus)) . ")
                    AND vs.status = 1
                    AND v.status = 1
                ORDER BY v.company ASC
            ");
        }
    
        $vendorList = [];
        foreach ($vendors as $row) {
            $vendorList[$row['v']['id']] = $row['v']['company'];
        }
    
        echo json_encode($vendorList);
    }
    
    public function fetch_indent_items() 
    {
        $this->autoRender = false; // Disable view rendering
        $indentId = $this->request->data('indent_id');
        
        // $indent_items=$this->Inventory_internal_indent_items->query("SELECT * FROM `inventory_internal_indent_items`  where indent_id=$indentId  and status=1");
        $indent_items=$this->Inventory_internal_indent_items->query("SELECT * FROM `inventory_internal_indent_items`  where indent_id=$indentId  and status=1 and is_completed=0");

        $x=1;
        foreach ($indent_items as $indent_item) {

            $qty=$indent_item['inventory_internal_indent_items']['sku_quantity']-$indent_item['inventory_internal_indent_items']['completed_quantity'];

            $vendorOptions .= "
            <tr>
                <td>".$x."</td>
                <td>".$indent_item['inventory_internal_indent_items']['sku_name']."</td>
                <td>".$indent_item['inventory_internal_indent_items']['sku_brand']."</td>
                <td>".$indent_item['inventory_internal_indent_items']['sku_unit_name']."</td>
                <td>".$indent_item['inventory_internal_indent_items']['sku_price']."</td>
                <td>".($indent_item['inventory_internal_indent_items']['sku_total_tax_percentage'] ?? 0)." %</td>
                <td>".$qty."</td>
            </tr>";
            $x++;
        }
        echo $vendorOptions;
    }

    public function fetch_vendor_items() 
    {
        $this->autoRender = false; // Disable view rendering
        $vendorId = $this->request->data('vendor_id');
        $indentId = $this->request->data('indent_id');
        
        // $vendor_items=$this->Inventory_internal_indent_items->query("SELECT i.*,v.sku_price as price FROM `inventory_internal_indent_items` i JOIN `inventory_vendor_sku_served` v ON i.sku_id = v.skus_id WHERE i.indent_id = '$indentId' AND v.vendor_id = ".$vendorId." and v.status=1 and i.status=1");
        // $vendor_items=$this->Inventory_internal_indent_items->query("SELECT i.*,v.sku_price as price FROM `inventory_internal_indent_items` i JOIN `inventory_vendor_sku_served` v ON i.sku_id = v.skus_id WHERE i.indent_id = '$indentId' AND i.is_completed = 0 AND v.vendor_id = ".$vendorId." and v.status=1 and i.status=1");
        $vendor_items = $this->Inventory_internal_indent_items->query("
            SELECT 
                i.*,
                v.sku_price AS price,
                tax.total_tax_percent AS tax_percent
            FROM inventory_internal_indent_items i
        
            JOIN inventory_vendor_sku_served v 
                ON i.sku_id = v.skus_id
                AND v.vendor_id = ".$vendorId."
                AND v.status = 1
        
            LEFT JOIN (
                SELECT product_id, SUM(tax_percentage) AS total_tax_percent
                FROM inventory_sku_tax
                WHERE status = 1
                GROUP BY product_id
            ) tax 
                ON tax.product_id = i.sku_id
        
            WHERE 
                i.indent_id = '".$indentId."'
                AND i.is_completed = 0
                AND i.status = 1
        ");

        $x=1;
        
        foreach ($vendor_items as $vendor_item) {
            // print_r($vendor_item);exit;
            if($vendor_item['i']['sku_quantity']){
                // $quantity=$vendor_item['i']['sku_quantity'];
                $quantity=$vendor_item['i']['sku_quantity']-$vendor_item['i']['completed_quantity'];
            }else{
                $quantity=0;
            }
            $vendorOptions .= "
            <tr>
                <td>".$x."</td>
                <td>".$vendor_item['i']['sku_name']."</td>
                <td>".$vendor_item['i']['sku_brand']."</td>
                <td>".$vendor_item['i']['sku_unit_name']."</td>
                <td><input type='number' name='prices[".$vendor_item['i']['sku_id']."]' value='".$vendor_item['v']['price']."' class='form-control' step='any' /></td>
                <td>".($vendor_item['tax']['tax_percent'] ?? 0)." %</td>
                <td><input type='number' name='quantity[".$vendor_item['i']['sku_id']."]' value='".$quantity."' class='form-control  vendor-qty' step='any'   max='".$quantity."'  data-max='".$quantity."' /></td>
                <td style='display:flex; gap:5px;'>

                    <select name='discount_type[".$vendor_item['i']['sku_id']."]'
                    class='form-control discount-type'
                    data-id='".$vendor_item['i']['sku_id']."'
                    style='width:150px'>

                        <option value='flat'>Flat</option>
                        <option value='percentage'>Percentage</option>

                    </select>

                    <input type='number'
                    name='sku_discount[".$vendor_item['i']['sku_id']."]'
                    value='0'
                    class='form-control sku-discount'
                    step='any'
                    min='0'
                    placeholder='Amount'
                    id='discount_".$vendor_item['i']['sku_id']."'
                    style='width:90px' />

                </td>
            </tr>";
            $x++;
        }
        echo $vendorOptions;
    }
    
    
    public function view_po()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Inventory_purchase_order->query("SELECT * FROM inventory_purchase_order where p_o_id=$id and status!=0");
        $this->set(compact('indents'));
        
        $items = $this->Inventory_purchase_order_item->query("SELECT * FROM inventory_purchase_order_items where p_o_id=$id and status!=0 and sku_quantity!=0 order by sku_name asc");
        
        $this->set(compact('items'));
        
        $stockinData = [];

        if ($indents[0]['inventory_purchase_order']['status'] == 4) {
        
            $stockins = $this->Inventory_stockin->find('all', [
                'conditions' => [
                    'p_o_id' => $id,
                    'status !=' => 0
                ],
                'order' => ['id ASC']
            ]);
        
            foreach ($stockins as $s) {
        
                $stockin_id = $s['Inventory_stockin']['stockin_id'];
        
                $stockin_items = $this->Inventory_stockin_item->find('all', [
                    'conditions' => [
                        'stockin_id' => $stockin_id,
                        'status !=' => 0
                    ],
                    'order' => ['sku_name ASC']
                ]);
        
                $stockinData[] = [
                    'stockin' => $s['Inventory_stockin'],
                    'items'   => $stockin_items
                ];
            }
        }
        
        $this->set(compact('stockinData'));
    }
    
    public function edit_po()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? 0;
        $userid = $authUser['id'];
        $username = $authUser['name'];
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $purchase_orders = $this->Inventory_purchase_order->query("SELECT * FROM inventory_purchase_order where p_o_id=$id");
        
        $internal_indent_id=$purchase_orders[0]['inventory_purchase_order']['internal_indent_id'];
        $vendorId=$purchase_orders[0]['inventory_purchase_order']['vendor_id'];
        
        // $vendor_items=$this->Inventory_internal_indent_items->query("SELECT i.*,v.sku_price as vprice,(SELECT sku_price FROM `inventory_purchase_order_items` WHERE p_o_id=$id and internal_indent_id=i.indent_id and sku_id=i.sku_id and status=1) AS psku_price,(SELECT sku_quantity FROM `inventory_purchase_order_items` WHERE p_o_id=$id and internal_indent_id=i.indent_id and sku_id=i.sku_id and status=1) AS psku_quantity FROM `inventory_internal_indent_items` i JOIN `inventory_vendor_sku_served` v ON i.sku_id = v.skus_id WHERE i.indent_id = '$internal_indent_id' AND v.vendor_id =$vendorId and v.status=1 and i.status=1");
                // $vendor_items=$this->Inventory_internal_indent_items->query("SELECT i.*,v.sku_price as vprice,(SELECT sku_price FROM `inventory_purchase_order_items` WHERE p_o_id=$id and internal_indent_id=i.indent_id and sku_id=i.sku_id and status=1) AS psku_price,(SELECT sku_quantity FROM `inventory_purchase_order_items` WHERE p_o_id=$id and internal_indent_id=i.indent_id and sku_id=i.sku_id and status=1) AS psku_quantity FROM `inventory_internal_indent_items` i JOIN `inventory_vendor_sku_served` v ON i.sku_id = v.skus_id WHERE i.indent_id = '$internal_indent_id' AND v.vendor_id =$vendorId and v.status=1 and i.status=1");
        $vendor_items = $this->Inventory_internal_indent_items->query("
            SELECT 
                i.*,
                v.sku_price AS vprice,
                p.sku_price AS psku_price,
                p.sku_total_tax_value AS psku_total_tax_value,
                p.sku_amount AS psku_amount,
                p.sku_quantity AS psku_quantity,
                p.sku_discount AS psku_discount,
                p.sku_discount_type AS psku_discount_type,
                tax.ssku_tax
            FROM inventory_internal_indent_items i
        
            JOIN inventory_vendor_sku_served v 
                ON i.sku_id = v.skus_id
                AND v.vendor_id = $vendorId
                AND v.status = 1
        
            LEFT JOIN inventory_purchase_order_items p
                ON p.p_o_id = $id
                AND p.internal_indent_id = i.indent_id
                AND p.sku_id = i.sku_id
                AND p.status = 1
        
            LEFT JOIN (
                SELECT product_id, SUM(tax_percentage) AS ssku_tax
                FROM inventory_sku_tax
                WHERE status = 1
                GROUP BY product_id
            ) tax ON tax.product_id = i.sku_id
        
            WHERE 
                i.indent_id = '$internal_indent_id'
                AND i.status = 1
        
            ORDER BY i.sku_name ASC
        ");


        $this->set(compact('vendor_items'));
        $this->set(compact('purchase_orders'));
        
        if ($this->request->is(array('post', 'put'))) {
            $today = date('Y-m-d H:i:s');
            
            $indent_id = $this->data['User']['indent'];
            $p_o_id = $this->data['User']['p_o_id'];
            $prices=$this->data['prices'];
            $quantities=$this->data['quantity'];
            $charge = $this->data['User']['charge'] ?? 0;
            $discounts = $this->data['discount'] ?? [];
            $discount_types = $this->data['discount_type'] ?? [];
            $po_date = $_POST['po_date'];

            $amount=0;
            $productamount=0;
            $total_discount=0;
            
            $this->Inventory_purchase_order_item->query("UPDATE inventory_purchase_order_items set status=0,sync=0,local_sync=0 WHERE p_o_id =". $p_o_id);
            
            $vendor = $this->Inventory_vendor->find('first', [
                'conditions' => ['Inventory_vendor.id' => $vendorId],
                'recursive' => -1
            ]);
        
            if($vendor['Inventory_vendor']['po_approval_required']){
                $postatus = 1;
            }else{
                $postatus = 2;
            }
            
            foreach ($quantities as $sku_id => $quantity) {
                if ($quantity != 0) {
                    $price = isset($prices[$sku_id]) ? $prices[$sku_id] : 0;
                    $discount = isset($discounts[$sku_id]) ? $discounts[$sku_id] : 0;
                    $discount_type = isset($discount_types[$sku_id]) ? $discount_types[$sku_id] : 'flat';

                    $sku_details = $this->Inventory_sku->query("SELECT * FROM inventory_skus where id=$sku_id");
                    
                    $product_taxes=$this->Inventory_sku_tax->query("select SUM(tax_percentage) as total_tax from inventory_sku_tax where product_id='$sku_id' and status =1 ");
                    $total_tax=round($product_taxes['0']['0']['total_tax'],2);
                    // $tax_value = round(($price*$quantity) * ($total_tax / 100),2);
                    // $skuamount=round(($price*$quantity) + $tax_value,2);
                    
                    $base_amount = $price * $quantity;

                    /* ------------------------------
                       DISCOUNT CALCULATION
                    ------------------------------ */

                    if ($discount_type == 'percentage') {

                        // prevent >100%
                        if ($discount > 100) {
                            $discount = 100;
                        }

                        $discount_value = round(($base_amount * $discount) / 100,2);

                    } else {

                        // prevent discount greater than item value
                        if ($discount > $base_amount) {
                            $discount = $base_amount;
                        }

                        $discount_value = round($discount,2);
                    }

                    $after_discount = $base_amount - $discount_value;
                    
                    /* tax after discount */
                    $tax_value = round($after_discount * ($total_tax / 100),2);
                    
                    $skuamount = round($after_discount + $tax_value,2);
                    
                    $data['Inventory_purchase_order_item']=array(
                        'p_o_id'=>$p_o_id,
                        'internal_indent_id'=>$indent_id,
                        'sku_id'=>$sku_id,
                        'sku_name'=>$sku_details[0]['inventory_skus']['name'],
                        'sku_unit'=>$sku_details[0]['inventory_skus']['unit'],
                        'sku_unit_name'=>$sku_details[0]['inventory_skus']['unit_name'],
                        'sku_price'=>$price,
                        'sku_quantity'=>$quantity,
                        'sku_total_tax_percentage' => $total_tax,
                        'sku_total_tax_value' => $tax_value,
                        'sku_amount' => $skuamount,
                        'sync'      =>0,
                        'local_sync' =>0,
                        'sku_discount' => $discount,              // raw input (5 or 50)
                        'sku_discount_type' => $discount_type,    // percentage / flat
                        'sku_discount_value' => $discount_value,  // calculated value
                    );
                    if($this->Inventory_purchase_order_item->saveAll($data['Inventory_purchase_order_item']))
                    {
                        
                    }else{
                        $this->Flash->error(__('PO Items could not be saved. Please, try again.'));
                    }
                    // $productamount=$quantity*$price;
                    $amount=$amount+$skuamount;
                    $total_discount = $total_discount + $discount_value;
                }
            }
            $approval_amount=approval_amount;
            if($amount>$approval_amount){
                $postatus=1;
            }
            
            if($postatus==2){
                $approved_by_id=$userid;
                $approved_by_name=$username;
                $approved_on=$today;
                $approved_amount=$amount+$charge;
            }else{
                $approved_by_id=0;
                $approved_by_name='';
                $approved_on=NULL;
                $approved_amount=0;
            }
            
            $total_amount = $amount + $charge;

            $this->Inventory_purchase_order->query("
                UPDATE inventory_purchase_order 
                SET 
                    status = '$postatus',
                    `charge` = '$charge',
                    total_amount = '$total_amount',
                    discount_value = '$total_discount',
                    po_date = '$po_date',
                    is_updated = 1,
                    sync = 0,
                    local_sync = 0
                WHERE status != 0 
                  AND p_o_id = '$p_o_id'
            ");
            
            $this->Inventory_purchase_order_item->query("UPDATE inventory_purchase_order_items SET status='$postatus',sync = 0,local_sync=0 WHERE  status!=0 and p_o_id =". $p_o_id);
            
            // ================= RECALCULATE INDENT ITEMS AFTER PO EDIT =================
            $indentItems = $this->Inventory_internal_indent_items->find('all', [
                'conditions' => [
                    'Inventory_internal_indent_items.indent_id' => $indent_id,
                    'Inventory_internal_indent_items.status' => 1
                ],
                'recursive' => -1
            ]);
            
            $allItemsCompleted = true;
            
            foreach ($indentItems as $item) {
            
                $itemId    = $item['Inventory_internal_indent_items']['Id'];
                $skuId     = $item['Inventory_internal_indent_items']['sku_id'];
                $indentQty = (float)$item['Inventory_internal_indent_items']['sku_quantity'];
            
                // Sum of ALL ACTIVE PO quantities for this indent + SKU
                $poQtyData = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => [
                        'Inventory_purchase_order_item.internal_indent_id' => $indent_id,
                        'Inventory_purchase_order_item.sku_id' => $skuId,
                        'Inventory_purchase_order_item.status !=' => 0
                    ],
                    'fields' => [
                        'SUM(Inventory_purchase_order_item.sku_quantity) as total_qty'
                    ],
                    'recursive' => -1
                ]);
            
                $totalPoQty = (float)($poQtyData[0]['total_qty'] ?? 0);
                // Prevent over-completion
                if ($totalPoQty > $indentQty) {
                    $totalPoQty = $indentQty;
                }
            
                // Update indent item
                $this->Inventory_internal_indent_items->updateAll(
                    [
                        'Inventory_internal_indent_items.completed_quantity' => $totalPoQty,
                        'Inventory_internal_indent_items.is_completed' =>
                            ($totalPoQty >= $indentQty) ? 1 : 0
                    ],
                    [
                        'Inventory_internal_indent_items.id' => $itemId,
                        'Inventory_internal_indent_items.status' => 1
                    ]
                );
            
                if ($totalPoQty < $indentQty) {
                    $allItemsCompleted = false;
                }
            }
            
            // ================= UPDATE INDENT STATUS =================
            
            $this->Inventory_internal_indent->updateAll(
                [
                    'Inventory_internal_indent.is_completed' =>
                        $allItemsCompleted ? 1 : 0,
                    'Inventory_internal_indent.modified' =>
                        "'" . date('Y-m-d H:i:s') . "'"
                ],
                [
                    'Inventory_internal_indent.indent_id' => $indent_id,
                    'Inventory_internal_indent.status' => 1
                ]
            );

            $this->Flash->success(__('PO has been Updated.'));
            return $this->redirect(array('action' => 'po_list'));
        }
    }
    public function process_po() 
    {
        $this->autoRender = false;
    
        if ($this->request->is('post')) {
            $poid   = $this->request->data['_id'];
            $items  = $this->request->data['_items'];
            $charge = $this->request->data['_charge'] ?? 0;
            
            $today = date('Y-m-d H:i:s');
            $id    = $this->Session->read('Auth.User.id');
        
            $user = $this->User->find('first', [
                'conditions' => ['User.id' => $id],
                'fields'     => ['User.name'],
                'recursive'  => -1
            ]);
            $name = $user['User']['name'];
        
            $amount                       = 0;
            $total_processed_disc_value   = 0; // sum of process_discount_value across all items
            
            foreach ($items as $item) {
                $itemId   = (int)$item['item_id'];
                $quantity = (float)$item['quantity'];

                // Discount inputs sent from the view for this process action
                $processDiscType  = isset($item['discount_type']) ? $item['discount_type'] : 'flat';
                $processDiscInput = (float)($item['discount'] ?? 0); // raw input: 5 (%) or 50.00 (flat ₹)
                
                $poItem = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => [
                        'Inventory_purchase_order_item.id'     => $itemId,
                        'Inventory_purchase_order_item.status' => 2
                    ],
                    'fields'    => ['Inventory_purchase_order_item.sku_id', 'sku_price'],
                    'recursive' => -1
                ]);
                $sku_id = $poItem['Inventory_purchase_order_item']['sku_id'];
                $price  = $poItem['Inventory_purchase_order_item']['sku_price'];
        
                $taxResult = $this->Inventory_sku_tax->query(
                    "SELECT SUM(tax_percentage) AS total_tax FROM inventory_sku_tax WHERE product_id = '$sku_id' and status=1"
                );
                $total_tax = round($taxResult[0][0]['total_tax'], 2);
        
                $baseAmount = $price * $quantity;

                // Calculate process_discount_value from process_discount + process_discount_type
                if ($processDiscType === 'percentage') {
                    if ($processDiscInput > 100) { $processDiscInput = 100; }
                    $processDiscValue = round(($baseAmount * $processDiscInput) / 100, 2);
                } else {
                    if ($processDiscInput > $baseAmount) { $processDiscInput = $baseAmount; }
                    $processDiscValue = $processDiscInput; // flat: input IS the ₹ value
                }

                $baseP     = $baseAmount - $processDiscValue;
                $tax_value = round($baseP * ($total_tax / 100), 2);
                $skuamount = round($baseP + $tax_value, 2);
        
                $this->Inventory_purchase_order_item->updateAll(
                    [
                        'Inventory_purchase_order_item.processed_quantity'        => $quantity,
                        'Inventory_purchase_order_item.processed_total_tax_value' => $tax_value,
                        'Inventory_purchase_order_item.processed_amount'          => $skuamount,
                        // UPDATED: write ONLY to the process_discount_* columns — sku_discount_* and approve_discount_* are NOT touched here
                        'Inventory_purchase_order_item.process_discount'          => $processDiscInput, // raw input
                        'Inventory_purchase_order_item.process_discount_type'     => "'$processDiscType'",
                        'Inventory_purchase_order_item.process_discount_value'    => $processDiscValue, // calculated ₹
                        'Inventory_purchase_order_item.status'                    => 3,
                        'Inventory_purchase_order_item.sync'                      => 0,
                        'Inventory_purchase_order_item.local_sync'                => 0
                    ],
                    [
                        'Inventory_purchase_order_item.id'     => $itemId,
                        'Inventory_purchase_order_item.p_o_id' => $poid,
                        'Inventory_purchase_order_item.status' => 2
                    ]
                );
        
                $amount                     += $skuamount;
                $total_processed_disc_value += $processDiscValue;
            }
        
            $this->Inventory_purchase_order->updateAll(
                [
                    'Inventory_purchase_order.status'                   => 3,
                    'Inventory_purchase_order.processed_by_id'          => $id,
                    'Inventory_purchase_order.processed_by_name'        => "'$name'",
                    'Inventory_purchase_order.processed_on'             => "'$today'",
                    'Inventory_purchase_order.processed_charge'         => $charge,
                    'Inventory_purchase_order.processed_amount'         => $amount + $charge,
                    // UPDATED: dedicated processed_discount_value column on PO header
                    'Inventory_purchase_order.processed_discount_value' => $total_processed_disc_value,
                    'Inventory_purchase_order.sync'                     => 0,
                    'Inventory_purchase_order.local_sync'               => 0
                ],
                [
                    'Inventory_purchase_order.p_o_id' => $poid,
                    'Inventory_purchase_order.status' => 2
                ]
            );
        
            echo json_encode(['status' => true]);
            exit;
        }
    }


    public function approve_po() 
    {
        $this->autoRender = false;
    
        if ($this->request->is('post')) {
            $poid   = $this->request->data['_id'];
            $items  = $this->request->data['_items'];
            $charge = $this->request->data['_charge'] ?? 0;
            
            $today = date('Y-m-d H:i:s');
            $id    = $this->Session->read('Auth.User.id');
        
            $user = $this->User->find('first', [
                'conditions' => ['User.id' => $id],
                'fields'     => ['User.name'],
                'recursive'  => -1
            ]);
            $name = $user['User']['name'];
            
            $amount                      = 0;
            $total_approved_disc_value   = 0; // sum of approve_discount_value across all items
        
            foreach ($items as $item) {
                $itemId   = (int)$item['item_id'];
                $quantity = (float)$item['quantity'];

                // Discount inputs sent from the view for this approval action
                $approveDiscType  = isset($item['discount_type']) ? $item['discount_type'] : 'flat';
                $approveDiscInput = (float)($item['discount'] ?? 0); // raw input: 5 (%) or 50.00 (flat ₹)
        
                $poItem = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => [
                        'Inventory_purchase_order_item.id'     => $itemId,
                        'Inventory_purchase_order_item.status' => 1
                    ],
                    'fields'    => ['Inventory_purchase_order_item.sku_id', 'sku_price'],
                    'recursive' => -1
                ]);
                $sku_id = $poItem['Inventory_purchase_order_item']['sku_id'];
                $price  = $poItem['Inventory_purchase_order_item']['sku_price'];
        
                $taxResult = $this->Inventory_sku_tax->query(
                    "SELECT SUM(tax_percentage) AS total_tax FROM inventory_sku_tax WHERE product_id = '$sku_id' and status=1"
                );
                $total_tax = round($taxResult[0][0]['total_tax'], 2);
        
                $baseAmount = $price * $quantity;

                // Calculate approve_discount_value from approve_discount + approve_discount_type
                if ($approveDiscType === 'percentage') {
                    if ($approveDiscInput > 100) { $approveDiscInput = 100; }
                    $approveDiscValue = round(($baseAmount * $approveDiscInput) / 100, 2);
                } else {
                    if ($approveDiscInput > $baseAmount) { $approveDiscInput = $baseAmount; }
                    $approveDiscValue = $approveDiscInput; // flat: input IS the ₹ value
                }

                $base      = $baseAmount - $approveDiscValue;
                $tax_value = round($base * ($total_tax / 100), 2);
                $skuamount = round($base + $tax_value, 2);
        
                $this->Inventory_purchase_order_item->updateAll(
                    [
                        'Inventory_purchase_order_item.approved_quantity'        => $quantity,
                        'Inventory_purchase_order_item.approved_total_tax_value' => $tax_value,
                        'Inventory_purchase_order_item.approved_amount'          => $skuamount,
                        // UPDATED: write ONLY to the approve_discount_* columns — sku_discount_* are NOT touched here
                        'Inventory_purchase_order_item.approve_discount'         => $approveDiscInput, // raw input
                        'Inventory_purchase_order_item.approve_discount_type'    => "'$approveDiscType'",
                        'Inventory_purchase_order_item.approve_discount_value'   => $approveDiscValue, // calculated ₹
                        'Inventory_purchase_order_item.status'                   => 2,
                        'Inventory_purchase_order_item.sync'                     => 0,
                        'Inventory_purchase_order_item.local_sync'               => 0
                    ],
                    [
                        'Inventory_purchase_order_item.id'     => $itemId,
                        'Inventory_purchase_order_item.p_o_id' => $poid,
                        'Inventory_purchase_order_item.status' => 1
                    ]
                );
        
                $amount                    += $skuamount;
                $total_approved_disc_value += $approveDiscValue;
            }
        
            $this->Inventory_purchase_order->updateAll(
                [
                    'Inventory_purchase_order.status'                  => 2,
                    'Inventory_purchase_order.approved_by_id'          => $id,
                    'Inventory_purchase_order.approved_by_name'        => "'$name'",
                    'Inventory_purchase_order.approved_on'             => "'$today'",
                    'Inventory_purchase_order.approved_charge'         => $charge,
                    'Inventory_purchase_order.approved_amount'         => $amount + $charge,
                    // UPDATED: dedicated approved_discount_value column on PO header
                    'Inventory_purchase_order.approved_discount_value' => $total_approved_disc_value,
                    'Inventory_purchase_order.sync'                    => 0,
                    'Inventory_purchase_order.local_sync'              => 0
                ],
                [
                    'Inventory_purchase_order.p_o_id' => $poid,
                    'Inventory_purchase_order.status' => 1
                ]
            );
        
            echo json_encode(['status' => true]);
            exit;
        }
    }

    
    public function po_change_status()
    {
        $this->autoRender = false;
    
        if (!$this->request->is('post')) {
            echo json_encode(['status' => false]);
            return;
        }
    
        $poId = (int)$this->request->data('_id');
    
        // ================= FETCH PO =================
        $po = $this->Inventory_purchase_order->find('first', [
            'conditions' => ['Inventory_purchase_order.id' => $poId],
            'recursive'  => -1
        ]);
    
        if (empty($po)) {
            echo json_encode(['status' => false]);
            return;
        }
    
        $indentId = $po['Inventory_purchase_order']['internal_indent_id'];
        $p_o_id   = $po['Inventory_purchase_order']['p_o_id'];
    
        // ================= TOGGLE STATUS =================
        $currentStatus = (int)$po['Inventory_purchase_order']['status'];
        $newStatus     = ($currentStatus == 1) ? 0 : 1;
    
        // ==================================================
        // 🔥 BLOCK OVER-ALLOCATION WHEN ACTIVATING PO
        // ==================================================
        if ($newStatus == 1) {
    
            $poItems = $this->Inventory_purchase_order_item->find('all', [
                'conditions' => [
                    'Inventory_purchase_order_item.p_o_id' => $p_o_id
                ],
                'recursive' => -1
            ]);
    
            foreach ($poItems as $poItem) {
    
                $skuId = $poItem['Inventory_purchase_order_item']['sku_id'];
                $sku_name = $poItem['Inventory_purchase_order_item']['sku_name'];
                $poQty = (float)$poItem['Inventory_purchase_order_item']['sku_quantity'];
    
                // Sum ACTIVE quantities from OTHER POs
                $activeQtyData = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => [
                        'Inventory_purchase_order_item.internal_indent_id' => $indentId,
                        'Inventory_purchase_order_item.sku_id'             => $skuId,
                        'Inventory_purchase_order_item.status'             => 1,
                        'Inventory_purchase_order_item.p_o_id !='          => $p_o_id
                    ],
                    'fields' => [
                        'SUM(Inventory_purchase_order_item.sku_quantity) AS total_qty'
                    ],
                    'recursive' => -1
                ]);
    
                $activeQty = (float)($activeQtyData[0]['total_qty'] ?? 0);
    
                // Get indent required quantity
                $indentItem = $this->Inventory_internal_indent_items->find('first', [
                    'conditions' => [
                        'Inventory_internal_indent_items.indent_id' => $indentId,
                        'Inventory_internal_indent_items.sku_id'    => $skuId
                    ],
                    'recursive' => -1
                ]);
    
                $indentQty = (float)$indentItem['Inventory_internal_indent_items']['sku_quantity'];
    
                // ❌ STOP if activation exceeds indent qty
                if (($activeQty + $poQty) > $indentQty) {
                    echo json_encode([
                        'status'  => false,
                        'message' => "Cannot activate PO. SKU {$sku_name} exceeds indent quantity."
                    ]);
                    return;
                }
            }
        }
    
        // ================= UPDATE PO =================
        $this->Inventory_purchase_order->save([
            'id'         => $poId,
            'status'     => $newStatus,
            'sync'       => 0,
            'local_sync' => 0
        ]);
    
        // ================= UPDATE PO ITEMS =================
        $this->Inventory_purchase_order_item->updateAll(
            [
                'Inventory_purchase_order_item.status'     => "'" . $newStatus . "'",
                'Inventory_purchase_order_item.sync'       => '0',
                'Inventory_purchase_order_item.local_sync' => '0'
            ],
            [
                'Inventory_purchase_order_item.p_o_id' => $p_o_id
            ]
        );
    
        // ==================================================
        // 🔥 ALWAYS RECALCULATE INDENT FROM ACTIVE POs
        // ==================================================
        $indentItems = $this->Inventory_internal_indent_items->find('all', [
            'conditions' => [
                'Inventory_internal_indent_items.indent_id' => $indentId,
                'Inventory_internal_indent_items.status'    => 1
            ],
            'recursive' => -1
        ]);
    
        $allItemsCompleted = true;
    
        foreach ($indentItems as $item) {
    
            $itemId    = $item['Inventory_internal_indent_items']['Id'];
            $skuId     = $item['Inventory_internal_indent_items']['sku_id'];
            $indentQty = (float)$item['Inventory_internal_indent_items']['sku_quantity'];
    
            // Sum ONLY ACTIVE PO quantities
            $poQtyData = $this->Inventory_purchase_order_item->find('first', [
                'conditions' => [
                    'Inventory_purchase_order_item.internal_indent_id' => $indentId,
                    'Inventory_purchase_order_item.sku_id'             => $skuId,
                    'Inventory_purchase_order_item.status'             => 1
                ],
                'fields' => [
                    'SUM(Inventory_purchase_order_item.sku_quantity) AS total_qty'
                ],
                'recursive' => -1
            ]);
    
            $totalPoQty = (float)($poQtyData[0]['total_qty'] ?? 0);
    
            // 🔒 HARD CAP at indent quantity
            if ($totalPoQty > $indentQty) {
                $totalPoQty = $indentQty;
            }
    
            $isCompleted = ($totalPoQty >= $indentQty) ? 1 : 0;
    
            // Update indent item
            $this->Inventory_internal_indent_items->updateAll(
                [
                    'Inventory_internal_indent_items.completed_quantity' =>
                        "'" . $totalPoQty . "'",
                    'Inventory_internal_indent_items.is_completed' =>
                        "'" . $isCompleted . "'"
                ],
                [
                    'Inventory_internal_indent_items.Id' => $itemId
                ]
            );
    
            if ($isCompleted == 0) {
                $allItemsCompleted = false;
            }
        }
    
        // ================= UPDATE INDENT HEADER =================
        $this->Inventory_internal_indent->updateAll(
            [
                'Inventory_internal_indent.is_completed' =>
                    "'" . ($allItemsCompleted ? 1 : 0) . "'",
                'Inventory_internal_indent.po_locked' =>0,
                'Inventory_internal_indent.modified' =>
                    "'" . date('Y-m-d H:i:s') . "'"
            ],
            [
                'Inventory_internal_indent.indent_id' => $indentId
            ]
        );
    
        echo json_encode(['status' => true]);
    }


    public function stockin()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? '';
    
        $this->layout = "users";
        $id = $_POST['po'] ?? null;
        $this->set(compact('id'));
    
        $conditions2 = ['status' => 1,'type' => 'DC'];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            // Normalize location IDs to array
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions2['id IN'] = array_map('trim', $userLocationIds);
        }
        $processedpoConditions = [
            "status" => 3,
            "direct_purchase" => 0,
            "location_type" => 'DC'
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $processedpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        $processedpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $processedpoConditions
        ]);
        
        $stockedinpoConditions = [
            "status" => 4,
            "direct_purchase" => 0,
            "location_type" => 'DC'
        ];
        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $stockedinpoConditions['location_id IN'] = $conditions2['id IN'];
        }
        $stockedinpo = $this->Inventory_purchase_order->find('count', [
            'conditions' => $stockedinpoConditions
        ]);
        $this->set(compact('processedpo','stockedinpo'));
        

        if ($id) {
            // Fetch PO
            
            $poQuerylocationchk = "SELECT * FROM inventory_purchase_order WHERE p_o_id = $id and location_type='DC'";
            $indentschk = $this->Inventory_purchase_order->query($poQuerylocationchk);
    
            if (empty($indentschk)) {
                $this->set('po_error', 'PO Not Available for this location'); // trigger JS alert
                return;
            }
            
            $poQuery = "SELECT * FROM inventory_purchase_order WHERE p_o_id = $id";
            $indents = $this->Inventory_purchase_order->query($poQuery);
    
            if (empty($indents)) {
                $this->set('po_error', 'PO Not Found'); // trigger JS alert
                return;
            }
    
            $po = $indents[0]['inventory_purchase_order'];
            
            if ($po['status'] == 4) {
                $this->set('po_error', 'PO Already Stocked IN');
                return;
            } elseif ($po['status'] < 3) {
                $this->set('po_error', 'PO is not Processed');
                return;
            } elseif ($po['status'] < 2) {
                $this->set('po_error', 'PO is not Approved');
                return;
            }

    
            if ($userRole != 'admin' && $po['location_id'] != $userLocationId) {
                $this->set('po_error', 'Location Not Found'); // trigger JS alert
                return;
            }
            // print_r($indents);exit;
            // All good, load items
            $items = $this->Inventory_purchase_order_item->query(
                "SELECT * FROM inventory_purchase_order_items WHERE p_o_id = $id AND status = 3"
            );
            $this->set(compact('indents', 'items'));
        }
    }

    public function stockin_po() 
    {
        $this->autoRender = false;
    
        if ($this->request->is('post')) {
            $poid       = $this->request->data['_id'];
            $invoice    = trim($this->request->data['_invoice']);
            $charge     = trim($this->request->data['_charge']);
            $quantities = $this->request->data['_quantities'];     // sku_id => quantity
            $discounts  = $this->request->data['_discounts']      ?? []; // sku_id => raw discount input
            // UPDATED: receive discount_type per sku from the view
            $discount_types = $this->request->data['_discount_types'] ?? []; // sku_id => 'flat'|'percentage'

            $today    = date('Y-m-d H:i:s');
            $id       = $this->Session->read('Auth.User.id');

            $poQuery  = "SELECT * FROM inventory_purchase_order WHERE p_o_id = $poid";
            $indents  = $this->Inventory_purchase_order->query($poQuery);
            $store_id = $indents[0]['inventory_purchase_order']['location_id'];
            $name     = $indents[0]['inventory_purchase_order']['location_name'];

            // Generate unique stockin_id
            do {
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existing = $this->Inventory_purchase_order->find('first', [
                    'conditions' => ['stockin_id' => $txnid, 'status !=' => 0]
                ]);
            } while ($existing);

            $stockin_skus = $this->Inventory_purchase_order_item->find('all', [
                'conditions' => ['p_o_id' => $poid, 'status !=' => 0]
            ]);

            $amount                     = 0;
            $total_stockin_disc_value   = 0; // UPDATED: sum of stockin_discount_value across all items

            foreach ($stockin_skus as $stockin_sku) {
                $sku    = $stockin_sku['Inventory_purchase_order_item'];
                $sku_id = $sku['sku_id'];

                if (!isset($quantities[$sku_id])) continue;

                $qty = floatval($quantities[$sku_id]);

                // UPDATED: read per-sku discount_type and raw discount input
                $stockinDiscType  = isset($discount_types[$sku_id]) ? $discount_types[$sku_id] : 'flat';
                $stockinDiscInput = isset($discounts[$sku_id])      ? floatval($discounts[$sku_id]) : 0;

                $poItem = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => [
                        'Inventory_purchase_order_item.sku_id'    => $sku_id,
                        'Inventory_purchase_order_item.p_o_id'    => $poid,
                        'Inventory_purchase_order_item.status !=' => 0
                    ],
                    'fields'    => ['sku_price'],
                    'recursive' => -1
                ]);
                $price = $poItem['Inventory_purchase_order_item']['sku_price'];

                $product_taxes = $this->Inventory_sku_tax->query(
                    "SELECT SUM(tax_percentage) AS total_tax FROM inventory_sku_tax WHERE product_id='$sku_id' AND status=1"
                );
                $total_tax = round($product_taxes[0][0]['total_tax'], 2);

                $base_amount = $price * $qty;

                // UPDATED: flat vs percentage discount logic — mirrors all other stages exactly
                if ($stockinDiscType === 'percentage') {
                    if ($stockinDiscInput > 100) {
                        $stockinDiscInput = 100;
                    }
                    $stockinDiscValue = round(($base_amount * $stockinDiscInput) / 100, 2);
                } else {
                    if ($stockinDiscInput > $base_amount) {
                        $stockinDiscInput = $base_amount;
                    }
                    $stockinDiscValue = $stockinDiscInput; // flat: input IS the ₹ value
                }

                $after_discount = $base_amount - $stockinDiscValue;
				$unit_price_after_dis = $after_discount/$qty;
                $tax_value      = round($after_discount * ($total_tax / 100), 2);
                $skuamount      = round($after_discount + $tax_value, 2);
				

                // UPDATED: write ONLY to stockin_discount_* columns — no other discount columns touched
                $this->Inventory_purchase_order_item->updateAll(
                    [
                        'status'                => 4,
                        'sync'                  => 0,
                        'local_sync'            => 0,
                        'stockin_quantity'      => $qty,
                        'stockin_total_tax_value' => $tax_value,
                        'stockin_amount'        => $skuamount,
                        // UPDATED: dedicated stockin_discount_* columns
                        'stockin_discount'      => $stockinDiscInput,        // raw input (5 or 50.00)
                        'stockin_discount_type' => "'$stockinDiscType'",     // 'flat' or 'percentage'
                        'stockin_discount_value'=> $stockinDiscValue         // calculated ₹ value
                    ],
                    [
                        'p_o_id'    => $poid,
                        'sku_id'    => $sku_id,
                        'status !=' => 0
                    ]
                );

                $amount                   += $skuamount;
                $total_stockin_disc_value += $stockinDiscValue; // UPDATED: accumulate ₹ discount values

                // Update stock ledger
                $ledgerprevdetails = $this->Stock_ledger->find('first', [
                    'conditions' => ['sku_id' => $sku_id, 'type' => 'DC', 'item_type' => 'SKU', 'store_id' => $store_id],
                    'fields'     => ['actual_balance'],
                    'order'      => ['id DESC'],
                    'recursive'  => -1
                ]);

                $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance'])
                    ? $ledgerprevdetails['Stock_ledger']['actual_balance']
                    : 0;

                $newQuantity = $qty + $ledger_prev_quantity;

                $ledgerData['Stock_ledger'] = [
                    'store_id'       => $store_id,
                    'sku_id'         => $sku_id,
                    'sku_name'       => $sku['sku_name'],
                    'sku_price'      => $unit_price_after_dis,
                    'unit_id'        => $sku['sku_unit'],
                    'unit_name'      => $sku['sku_unit_name'],
                    'record_id'      => $txnid,
                    'record_type'    => 'stockin',
                    'quantity'       => round($qty,2),
                    'balance_stock'  => round($newQuantity,2),
                    'actual_balance' => round($newQuantity,2),
                    'quantity_type'  => 'credit',
                    'type'           => 'DC',
                    'sync'           => 0,
                    'local_sync'     => 0,
                    'created'        => date('Y-m-d H:i:s')
                ];
                $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
            }

            $amount = $charge + $amount;

            // UPDATED: write stockin_discount_value to its dedicated PO header column
            $this->Inventory_purchase_order->query("UPDATE inventory_purchase_order SET
                stockin_id             = '$txnid',
                status                 = 4,
                stockin_on             = '$today',
                stockin_by_id          = $id,
                stockin_by_name        = '$name',
                stockin_charge         = '$charge',
                stockin_amount         = '$amount',
                invoice_no             = '$invoice',
                stockin_discount_value = '$total_stockin_disc_value',
                sync                   = 0,
                local_sync             = 0
                WHERE p_o_id = '$poid' AND status != 0");
			
            echo json_encode(['status' => true]);
        }
    }

    
    public function po_pdf() {

        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post','put'])) {

            $po_id = $this->request->data['Report']['poid'];

            // PO + Vendor
            $indents = $this->Inventory_purchase_order->query(
                "SELECT * FROM inventory_purchase_order
                 JOIN inventory_vendors ON inventory_purchase_order.vendor_id = inventory_vendors.id
                 WHERE inventory_purchase_order.p_o_id = ?",
                [$po_id]
            );

            // Items
            $items = $this->Inventory_purchase_order_item->query(
                "SELECT * FROM inventory_purchase_order_items
                 WHERE p_o_id = ? AND status != 0",
                [$po_id]
            );

            $status      = $indents[0]['inventory_purchase_order']['status'];
            $location_id = $indents[0]['inventory_purchase_order']['location_id'];

            $locationdetail = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location_id]
            ]);

            // ================= STATUS BASED COLUMNS =================
            switch ($status) {
                case 2:
                    $qtyCol      = 'approved_quantity';
                    $taxCol      = 'approved_total_tax_value';
                    $discountCol = 'approve_discount_value';   // UPDATED: approve stage discount
                    break;
                case 3:
                    $qtyCol      = 'processed_quantity';
                    $taxCol      = 'processed_total_tax_value';
                    $discountCol = 'process_discount_value';   // UPDATED: process stage discount
                    break;
                case 4:
                    $qtyCol      = 'stockin_quantity';
                    $taxCol      = 'stockin_total_tax_value';
                    $discountCol = 'stockin_discount_value';   // UPDATED: stockin stage discount
                    break;
                default: // status 1
                    $qtyCol      = 'sku_quantity';
                    $taxCol      = 'sku_total_tax_value';
                    $discountCol = 'sku_discount_value';       // UPDATED: create stage discount
            }

            // ================= GST TYPE =================
            $vendorState   = trim($indents[0]['inventory_vendors']['state']);
            $locationState = trim($locationdetail['Location']['state']);

            $isIGST = (strcasecmp($vendorState, $locationState) !== 0) ? 1 : 0;
            $isCGST = $isIGST ? 0 : 1;

            // ================= TAX SUMMARY =================
            // UPDATED: taxable uses dynamic $discountCol instead of hardcoded sku_discount_value
            $taxSummary = $this->Inventory_purchase_order_item->query("
                SELECT
                    CONCAT(sku_total_tax_percentage,'%') AS tax_name,
                    SUM(sku_price * {$qtyCol} - {$discountCol}) AS taxable,

                    CASE
                        WHEN sku_total_tax_percentage > 0 AND {$isCGST} = 1
                        THEN SUM({$taxCol}) / 2
                        ELSE 0
                    END AS cgst,

                    CASE
                        WHEN sku_total_tax_percentage > 0 AND {$isCGST} = 1
                        THEN SUM({$taxCol}) / 2
                        ELSE 0
                    END AS sgst,

                    CASE
                        WHEN sku_total_tax_percentage > 0 AND {$isIGST} = 1
                        THEN SUM({$taxCol})
                        ELSE 0
                    END AS igst
 
                FROM inventory_purchase_order_items
                WHERE p_o_id = ?
                  AND status != 0
                GROUP BY sku_total_tax_percentage
                ORDER BY sku_total_tax_percentage
            ", [$po_id]);

            $this->set(compact(
                'po_id', 'indents', 'items', 'locationdetail',
                'taxSummary', 'status', 'isIGST'
            ));

            $this->render('po_pdf');
        }
    }


    
    
    public function waiter_list() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $locationCondition = ''; // always filter by active locations
        if ($userRole !== 'admin') {
            $locationCondition = "AND location_id IN (" . $userLocationId . ")";
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Order_waiter->query("SELECT * FROM order_waiters where created between '$startDatetime' and  '$endDatetime' $locationCondition ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_waiter()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $locationCondition = ['status' => 1];
        
        if ($userRole !== 'admin') {
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
        }
        $locations=$this->Location->find('all',array('conditions'=>array($locationCondition)));
        $this->set(compact('locations'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('Name could not be Blank'));
                return $this->redirect(array('action' => 'create_waiter'));
            }
            $phone = $this->data['User']['phone'];
            $pin=$this->data['User']['pin'];
            $pin_req = $this->data['User']['pin_req'];
            
            $namecheck=$this->Order_waiter->find('all',array('conditions'=>array('name'=>$name)));
            if(!empty($namecheck)){
                $this->Flash->error(__('Waiter Name already exist.'));
                return $this->redirect(array('action' => 'waiter_list'));
            }
            $phonecheck=$this->Order_waiter->find('all',array('conditions'=>array('phone'=>$phone)));
            if(!empty($phonecheck)){
                $this->Flash->error(__('Waiter Phone already exist.'));
                return $this->redirect(array('action' => 'waiter_list'));
            }
            $pincheck=$this->Order_waiter->find('all',array('conditions'=>array('pin_number'=>$pin)));
            if(!empty($pincheck)){
                $this->Flash->error(__('Waiter Pin already exist.'));
                return $this->redirect(array('action' => 'waiter_list'));
            }
            $location_id =$this->data['User']['location'];
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location_id)));
            $locationname=$locationdetail['Location']['name'];
            
            $data['Order_waiter']=array(
                'name'=>$name,
                'phone'=>$phone,
                'location_id'=>$location_id,
                'location_name'=>$locationname,
                'pin_number'=>$pin,
                'is_pin_required'=>$pin_req,
                'sync'      =>0,
                'local_sync' =>0
            );
            
            if($this->Order_waiter->saveAll($data['Order_waiter']))
            {
                $this->Flash->success(__('Waiter has been saved.'));
                return $this->redirect(array('action' => 'waiter_list'));
            } else {
                $this->Flash->error(__('Waiter could not be saved. Please, try again.'));
            }
        }
    }
    
    public function waiter_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Order_waiter->id = $Id;
            
            $currentStatus = $this->Order_waiter->field('status', ['id' => $Id]);
            $newStatus = in_array($currentStatus, [1]) ? 0 : 1;
            
            if ($this->Order_waiter->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function edit_waiter()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        
        if ($this->data['User']['id']!='') {
          
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            $phone = $this->data['User']['phone'];
            $pin = $this->data['User']['pin'];
            $is_pin_required = $this->data['User']['pin_req'];
            
            $phonecheck=$this->Order_waiter->find('all',array('conditions'=>array('phone'=>$phone,'id !='=>$id)));
            if(!empty($phonecheck)){
                $this->Flash->error(__('Waiter Phone already exist.'));
                return $this->redirect(array('action' => 'waiter_list'));
            }
            $pincheck=$this->Order_waiter->find('all',array('conditions'=>array('pin_number'=>$pin,'id !='=>$id)));
            if(!empty($pincheck)){
                $this->Flash->error(__('Waiter Pin already exist.'));
                return $this->redirect(array('action' => 'waiter_list'));
            }
            $location = $this->data['User']['location'];
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location)));
            $locationname=$locationdetail['Location']['name'];
            
            $this->Order_table->query("UPDATE order_waiters SET name ='$name',phone='$phone',location_id ='$location',location_name='$locationname',pin_number='$pin',is_pin_required='$is_pin_required',sync = 0,local_sync = 0 WHERE id =". $id);
            $this->Flash->success(__('Waiter has been Updated.'));
            return $this->redirect(array('action' => 'waiter_list'));
        }else{
            $id=$_REQUEST['id'];
            
            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;


            $userdetail=$this->Order_waiter->find('first',array('conditions'=>array('Order_waiter.id'=>$id)));
            $this->set(compact('userdetail'));
            
            $locationCondition = ['status' => 1];
        
            if ($userRole !== 'admin') {
                $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
                $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
            }
            $locations=$this->Location->find('all',array('conditions'=>array($locationCondition)));
            $this->set(compact('locations'));
        }
        
    }
    
    public function stock_transfer()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Stock_transfer->query("SELECT * FROM stock_transfers where status=1 and created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_stock_tranfer()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        $userchk="SELECT * FROM `users`  where role='kitchen' and status=1"; 
        $transferto=$this->User->query($userchk);
        
        
        $user="SELECT * FROM `inventory_skus`  where inventory_skus.status=1 order by inventory_skus.name desc"; 
        $users=$this->Inventory_sku->query($user);
        $this->set(compact('users','transferto'));
        
    }
    
    public function add_stock_transfer() 
    {
        $this->autoRender = false; // Disable view rendering
        
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
            
        if(isset($_POST['checkedData'])){
            $checkeddatas=JSON_decode($_POST['checkedData'],true);
            $transfer_from=$_POST['tranferfrom'];
            $transfer_to=$_POST['transferto'];
            do {
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                
                $existingOTP = $this->Stock_transfer->find('first', array(
                    'conditions' => array(
                        'transfer_id' => $txnid
                    )
                ));
               
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $amount=0;
            $productamount=0;
            foreach($checkeddatas as $checkeddata){
                $skuid=$checkeddata['id'];
                $price=$checkeddata['price'];
                $sku_name=$checkeddata['sku_name'];
                $sku_brand=$checkeddata['sku_brand'];
                $unit_name=$checkeddata['unit_name'];
                $unit_id=$checkeddata['unit_id'];
                $quantity=$checkeddata['sku_quantity'];
                
                if(isset($quantity)){
            
                    $data['Stock_transfer_item']=array(
                        'transfer_id'=>$txnid,
                        'sku_id'=>$skuid,
                        'sku_name'=>$sku_name,
                        'sku_brand'=>$sku_brand,
                        'sku_unit'=>$unit_id,
                        'sku_unit_name'=>$unit_name,
                        'sku_price'=>$price,
                        'sku_quantity'=>$quantity,
                        'sync'      =>0,
                        'local_sync' =>0
                    );
                    
                    if($this->Stock_transfer_item->saveAll($data['Stock_transfer_item']))
                    {
                        
                        $id = $this->Session->read('Auth.User.id');
                        $username = $this->Location->query("SELECT id FROM locations WHERE type = 'DC' limit 1");
                        $store_id = $username[0]['locations']['id'];
                        
                        
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $skuid,'store_id'=>$store_id,'type'=>'DC','item_type'=>'SKU'],
                            'fields' => ['actual_balance'],
                            'order' => ['id DESC'],
                            'recursive' => -1
                        ]);
                        
                        
                        $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                            ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                            : 0;
                        
                        $newQuantity = $ledger_prev_quantity-$quantity;
                        
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $store_id,
                                'sku_id'          => $skuid,
                                'sku_name'        => $sku_name,
                                'sku_price'       => $price,
                                'unit_id'         => $unit_id,
                                'unit_name'       => $unit_name,
                                'record_id'       => $txnid,
                                'record_type'     => 'stock_transfer_to_kitchen',
                                'quantity'        => $quantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'type'            => 'DC',
                                'sync'      =>0,
                                'local_sync' =>0,
                                'created'         => date('Y-m-d H:i:s')
                        ];
                        if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                            $chk=false;
                            $this->Flash->error(__('Transfer error in ledger . Please, try again.'));
                        }
                        
                        $usernamekitchen = $this->User->query("SELECT location_id FROM users WHERE role = 'kitchen' and location_id='$store_id'");
                        $kithcen_store_id = $usernamekitchen[0]['users']['location_id'];
                        
                        $kithcneledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $skuid,'store_id'=>$kithcen_store_id,'type'=>'KITCHEN'],
                            'fields' => ['actual_balance'],
                            'order' => ['id DESC'],
                            'recursive' => -1
                        ]);
                        
                        $kitchen_ledger_prev_quantity = !empty($kithcneledgerprevdetails['Stock_ledger']['actual_balance']) 
                            ? $kithcneledgerprevdetails['Stock_ledger']['actual_balance'] 
                            : 0;
                        
                        $kithcnenewQuantity = $kitchen_ledger_prev_quantity+$quantity;
                        
                        $kithcneledgerData['Stock_ledger'] = [
                                'store_id'        => $kithcen_store_id,
                                'sku_id'          => $skuid,
                                'sku_name'        => $sku_name,
                                'sku_price'       => $price,
                                'unit_id'         => $unit_id,
                                'unit_name'       => $unit_name,
                                'record_id'       => $txnid,
                                'record_type'     => 'stock_transfer_from_warehouse',
                                'quantity'        => $quantity,
                                'balance_stock'   => $kithcnenewQuantity,
                                'actual_balance'  => $kithcnenewQuantity,
                                'quantity_type'   => 'credit',
                                'type'            => 'KITCHEN',
                                'sync'      =>0,
                                'local_sync' =>0,
                                'created'         => date('Y-m-d H:i:s')
                        ];
                        if(!$this->Stock_ledger->saveAll($kithcneledgerData['Stock_ledger'])){
                            $chk=false;
                            $this->Flash->error(__('Transfer error in ledger . Please, try again.'));
                        }
                        $chk=true;   
                    }else{
                        $chk=false;
                        $this->Flash->error(__('Transfer could not be saved. Please, try again.'));
                    }
                }
                $productamount=$quantity*$price;
                $amount=$amount+$productamount;
            }

            if($chk){
                $data['Stock_transfer']=array(
                    'transfer_id'=>$txnid,
                    'transfer_from'=>$transfer_from,
                    'transfer_to'=>$transfer_to,
                    'created_by'=>$id,
                    'sync'      =>0,
                    'local_sync' =>0
                );
                
                if($this->Stock_transfer->saveAll($data['Stock_transfer']))
                {
                    $responseArray = array('response_code' => 1, 'data' => 'saved');
                    echo json_encode($responseArray);
                }else{
                    $responseArray = array('response_code' => 0, 'data' => 'Transfer Items could not be saved. Please, try again.');
                    echo json_encode($responseArray);
                }
            }else{
                $responseArray = array('response_code' => 0, 'data' => 'Transfer Items could not be saved. Please, try again.');
                echo json_encode($responseArray);
            }
        }
    }
    
    public function view_stock_transfer()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $transfers = $this->Stock_transfer->query("SELECT * FROM stock_transfers where transfer_id=$id");
        $this->set(compact('transfers'));
        
        $items = $this->Stock_transfer_item->query("SELECT * FROM stock_transfer_items where transfer_id=$id and status!=0");
        
        $this->set(compact('items'));
    }
    
    public function delete_stock_transfer() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['_id'];
    
            // Update user status
            $this->Stock_transfer->id = $userId;
            if ($this->Stock_transfer->save(['status' => 0,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function kds() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $conditions = [
            'created BETWEEN ? AND ?' => [$startDatetime, $endDatetime]
        ];
        
        // if ($userRole !== 'admin') {
        //     // Add raw SQL condition as a string
        //     $conditions[] = "store_id IN ($userLocationId)";
        // }
        
        $users = $this->Pos_printer->find('all', [
            'conditions' => $conditions,
            'order' => ['id' => 'DESC']
        ]);

        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_kds()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $locationCondition = ['status' => 1]; // always filter by active locations
        
        if ($userRole !== 'admin') {
            // If $userLocationId is a single ID, make it an array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP automatically handles IN
        }
        
        $locations=$this->Location->find('all',array('conditions'=>$locationCondition));
        $this->set(compact('locations'));
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_kds'));
            }
            
            $ip = $this->data['User']['ip'];
        //     $location = $this->data['User']['location'];
        //     $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location)));
           // $locationname=$locationdetail['Location']['name'];
            
            $data['Pos_printer']=array(
                'name'=>$name,
                'ip'=>$ip,
                'sync'      =>0,
                'local_sync' =>0
            );
            
            if($this->Pos_printer->save($data['Pos_printer']))
            {
                $kds_id = $this->Pos_printer->id;
                // Update the same record with kds_id
                // $this->Pos_printer->id = $kds_id;
                // $this->Pos_printer->saveField('kds', $kds_id);
                $this->Pos_printer->updateAll(
                    [
                        'Pos_printer.kds'        => $kds_id,
                        'Pos_printer.sync'       => 0,
                        'Pos_printer.local_sync' => 0
                    ],
                    [
                        'Pos_printer.id' => $kds_id
                    ]
                );

                $this->Flash->success(__('Kds has been saved.'));
                return $this->redirect(array('action' => 'kds'));
            } else {
                $this->Flash->error(__('kds could not be saved. Please, try again.'));
            }
        }
    }
    
    public function kds_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Pos_printer->id = $Id;
            $newStatus = $this->Pos_printer->field('status') == 1 ? 0 : 1;
            
            if ($this->Pos_printer->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function fetch_pro_options() {
        $this->autoRender = false;
        $this->response->type('json');
    
        $products = $this->Catalog_product->find('all', [
            'conditions' => ['Catalog_product.package' => 0, 'Catalog_product.status' => 1],
            'fields' => ['Catalog_product.id', 'Catalog_product.name', 'Catalog_product.unit_name', 'Catalog_product.price'],
            'order' => ['Catalog_product.name' => 'asc']
        ]);
    
        $data = [];
        foreach ($products as $product) {
            $data[] = [
                'id' => $product['Catalog_product']['id'],
                'name' => $product['Catalog_product']['name'],
                'price' => $product['Catalog_product']['price'],
                'unit_name' => $product['Catalog_product']['unit_name']
            ];
        }
    
        echo json_encode(['response_code' => 1, 'data' => $data]);
        exit;
    }
    
    public function stock_level() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $today = date("Y-m-d");
        $currentTime = date("H:i", strtotime("+1 minutes"));
 
        $sel_date = $today;      // default
        $sel_time = $currentTime; // default

        $skuledger_startdate = date('Y-m-d', strtotime('-10 days'));
        $stocklevel_enddate   = $skuledger_enddate   = date('Y-m-d');
        $sku_id = null;
        
        $stocklevel_startdate = $sel_date.' '.$sel_time.':00';
        
        if ($this->request->is(['post', 'put'])) {
            if (isset($this->request->data['submit_stocklevel'])) {
                
                $sel_date=$this->request->data['sel_date'];
                $sel_time=$this->request->data['sel_time'];
            
                $stocklevel_startdate = $sel_date.' '.$sel_time.':00';
            }
    
            if (isset($this->request->data['submit_skutransactions'])) {
                $daterange = $this->request->data['daterange'] ?? '';
                $dates = explode(" - ", $daterange);
                if (count($dates) === 2) {
                    $skuledger_startdate = date('Y-m-d', strtotime(trim($dates[0])));
                    $skuledger_enddate = date('Y-m-d', strtotime(trim($dates[1])));
                }
                $sku_id = $this->request->data['SkuLedger']['sku'] ?? null;
            }
            
        }
        
        $this->set(compact('sel_date', 'sel_time'));

        $id = $this->Session->read('Auth.User.id');
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        $conditions = [
            'status' => 1,
            'type'   => 'DC'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
            $store_id = implode(',', $userLocationIds);
        }
        else{
            $username = $this->User->query("SELECT location_id FROM users WHERE id = $id");
            $store_id = $username[0]['users']['location_id'];
        }

        if (!empty($this->request->data['StockLevel']['cashier'])) {
            $store_id = $this->request->data['StockLevel']['cashier'];
            $transactions = $this->Stock_ledger->query("
                SELECT sl1.sku_id,sl1.sku_price,sl1.sku_name,s.stock,sl1.unit_name, sl1.actual_balance
                FROM stock_ledger sl1
                INNER JOIN (
                    SELECT sku_id, MAX(id) AS max_id
                    FROM stock_ledger
                    WHERE type = 'dc'  AND item_type = 'SKU' 
                      AND store_id IN ($store_id)
                      AND created < '$stocklevel_startdate'
                    GROUP BY sku_id
                ) latest ON sl1.id = latest.max_id
                LEFT  JOIN inventory_skus s ON s.id = sl1.sku_id
                WHERE sl1.type = 'DC' AND sl1.item_type = 'SKU' order by s.name asc
            ");
        } 
        // else{
            // $transactions = $this->Stock_ledger->query("
            // SELECT sl1.sku_id,sl1.sku_price,sl1.sku_name,sl1.unit_name, sl1.actual_balance
            // FROM stock_ledger sl1
            // INNER JOIN (
                // SELECT sku_id, MAX(id) AS max_id
                // FROM stock_ledger
                // WHERE type = 'dc'  AND item_type = 'SKU' 
                  // AND created BETWEEN '$stocklevel_startdate 00:00:01' AND '$stocklevel_enddate 23:59:59'
                // GROUP BY sku_id
            // ) latest ON sl1.id = latest.max_id
            // WHERE sl1.type = 'DC' AND sl1.item_type = 'SKU' 
        // ");
        // }
        
        
        $skus = $this->Inventory_sku->query("SELECT * FROM inventory_skus WHERE status=1 order by name asc");
        
        $skutransactions = [];
        if (!empty($sku_id)) {
            if($store_id){
                $startDatetime = $skuledger_startdate . ' ' . shiftstart;
                $endDatetime   = date('Y-m-d', strtotime($skuledger_enddate . ' +1 day')) . ' ' . shiftend;
               
                $skutransactions = $this->Stock_ledger->query("
                    SELECT sl.*, ipo.vendor_name,ii.location_name
						FROM stock_ledger sl 
						LEFT JOIN inventory_purchase_order ipo
							ON ipo.stockin_id = sl.record_id
						LEFT JOIN inventory_indent ii ON ii.indent_id = sl.record_id
						WHERE sl.created BETWEEN '$startDatetime' AND '$endDatetime'
						AND sl.type = 'DC'
						AND sl.sku_id = $sku_id
						AND sl.store_id IN ($store_id)
						AND sl.item_type = 'SKU'
						ORDER BY sl.id DESC
                ");
            }
            // else{
            //     $skutransactions = $this->Stock_ledger->query("
            //         SELECT * FROM stock_ledger 
            //         WHERE created BETWEEN '$skuledger_startdate 00:00:01' AND '$skuledger_enddate 23:59:59'
            //         AND type='DC' AND sku_id = $sku_id and item_type = 'SKU'
            //         ORDER BY id DESC
            //                         ");
            // }
        }
        
        $this->set('stocklevel_daterange', date('m/d/Y', strtotime($stocklevel_startdate)) . ' - ' . date('m/d/Y', strtotime($stocklevel_enddate)));
        $this->set('skuledger_daterange', date('m/d/Y', strtotime($skuledger_startdate)) . ' - ' . date('m/d/Y', strtotime($skuledger_enddate)));

            
        $users=$this->Location->find('all',array('conditions'=>$conditions));
                
	    $this->set(compact('users'));
    
        $this->set(compact('transactions', 'skus', 'skutransactions'));
    }

    public function stock_levelexport()
    {
        $date_range = $_GET['sdate'] ?? '';
    
        if (!$date_range) {
            throw new BadRequestException('Invalid date range.');
        }
    
        $id = $this->Session->read('Auth.User.id');
        $username = $this->User->query("SELECT location_id FROM users WHERE id = $id");
        $store_id = $username[0]['users']['location_id'];
    
        // Fetch store name
        $store_data = $this->Location->find('first', [
            'conditions' => ['Location.id' => $store_id],
            'fields' => ['Location.name']
        ]);
        $store_name = $store_data['Location']['name'] ?? 'Unknown Store';
    
        // ===============================
        // Fetch Stock Ledger Data (Same as View)
        // ===============================
        $transactions = $this->Stock_ledger->query("
            SELECT sl1.sku_id, sl1.sku_price, sl1.sku_name, sl1.unit_name,
                   s.stock, sl1.actual_balance
            FROM stock_ledger sl1
            INNER JOIN (
                SELECT sku_id, MAX(id) AS max_id
                FROM stock_ledger
                WHERE type = 'DC' 
                  AND item_type = 'SKU' 
                  AND store_id = $store_id
                  AND created < '$date_range'
                GROUP BY sku_id
            ) latest ON sl1.id = latest.max_id
            LEFT JOIN inventory_skus s ON s.id = sl1.sku_id
            WHERE sl1.type = 'DC' AND sl1.item_type = 'SKU'
            ORDER BY s.name ASC
        ");
    
        // ===============================
        // Prepare Excel Export
        // ===============================
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);
    
        if (PHP_SAPI == 'cli') {
            die('This example should only be run from a Web Browser');
        }
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()
            ->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("DC Stock Level Report")
            ->setSubject("Stock Report")
            ->setDescription("Exported DC stock level data.")
            ->setKeywords("stock excel")
            ->setCategory("Export File");
    
        $sheet = $objPHPExcel->setActiveSheetIndex(0);
    
        // ===============================
        // Header Section
        // ===============================
        $sheet->setCellValue('A1', "DC STOCK LEVEL REPORT");
        $sheet->mergeCells('A1:G1');
        $sheet->getStyle('A1:G1')->getFont()->setBold(true)->setSize(14);
    
        $sheet->setCellValue('A2', "Store: $store_name");
        $sheet->mergeCells('A2:G2');
        $sheet->getStyle('A2:G2')->getFont()->setBold(true)->setSize(12);
    
        $sheet->setCellValue('A3', "Date $date_range");
        $sheet->mergeCells('A3:G3');
        $sheet->getStyle('A3:G3')->getFont()->setBold(true)->setSize(11);
    
        // ===============================
        // Column Headers
        // ===============================
        $headers = ['Sr No.', 'SKU Name', 'Unit Name', 'Price', 'Required Qty', 'Available Qty', 'Value'];
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '5', $header);
            $sheet->getStyle($col . '5')->getFont()->setBold(true);
            $sheet->getColumnDimension($col)->setAutoSize(true);
            $col++;
        }
    
        // ===============================
        // Fill Data Rows
        // ===============================
        $row = 6;
        $count = 1;
        foreach ($transactions as $txn) {
            $data  = $txn['sl1'];
            $stock = $txn['s']['stock'] ?? 0;
            $value = round($data['sku_price'] * $data['actual_balance'], 2);
    
            $sheet->setCellValue("A$row", $count);
            $sheet->setCellValue("B$row", $data['sku_name']);
            $sheet->setCellValue("C$row", $data['unit_name']);
            $sheet->setCellValue("D$row", (float)$data['sku_price']);
            $sheet->setCellValue("E$row", (float)$stock);
            $sheet->setCellValue("F$row", (float)$data['actual_balance']);
            $sheet->setCellValue("G$row", $value);
    
            $row++;
            $count++;
        }
    
        // ===============================
        // Style and Output
        // ===============================
        $sheet->getStyle("A5:G5")->getFont()->setBold(true);
        $sheet->setTitle('DC Stock Level');
        $objPHPExcel->setActiveSheetIndex(0);
    
        // Output headers
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="DC_Stock_Level_Report.xls"');
        header('Cache-Control: max-age=0');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    public function kitchen_stock_level() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $stocklevel_startdate = $stocklevel_enddate = $skuledger_startdate = $skuledger_enddate = date('Y-m-d');
        $sku_id = null;
    
        if ($this->request->is(['post', 'put'])) {
            if (isset($this->request->data['submit_stocklevel'])) {
                $daterange = $this->request->data['daterange'] ?? '';
                $dates = explode(" - ", $daterange);
                if (count($dates) === 2) {
                    $stocklevel_startdate = date('Y-m-d', strtotime(trim($dates[0])));
                    $stocklevel_enddate = date('Y-m-d', strtotime(trim($dates[1])));
                }
                $startDatetime = $stocklevel_startdate . ' ' . shiftstart;
                $endDatetime   = date('Y-m-d', strtotime($stocklevel_enddate . ' +1 day')) . ' ' . shiftend;
            }
    
            if (isset($this->request->data['submit_skutransactions'])) {
                $daterange = $this->request->data['daterange'] ?? '';
                $dates = explode(" - ", $daterange);
                if (count($dates) === 2) {
                    $skuledger_startdate = date('Y-m-d', strtotime(trim($dates[0])));
                    $skuledger_enddate = date('Y-m-d', strtotime(trim($dates[1])));
                }
                $sku_id = $this->request->data['SkuLedger']['sku'] ?? null;
                $startDatetime = $skuledger_startdate . ' ' . shiftstart;
                $endDatetime   = date('Y-m-d', strtotime($skuledger_enddate . ' +1 day')) . ' ' . shiftend;
            
            }
            
        }
        $id = $this->Session->read('Auth.User.id');
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = [
            'status' => 1,
            'type'   => 'kitchen'
        ];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
             $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
            $store_id = implode(',', $userLocationIds);
        }
        else{
            $username = $this->User->query("SELECT location_id FROM users WHERE id = $id");
            $store_id = $username[0]['users']['location_id'];
        }

        if (!empty($this->request->data['StockLevel']['cashier'])) {
            $store_id = $this->request->data['StockLevel']['cashier'];
        } 
        
        $transactions = $this->Stock_ledger->query("
            SELECT sl1.sku_id,sl1.sku_price,sl1.sku_name,sl1.unit_name, sl1.actual_balance
            FROM stock_ledger sl1
            INNER JOIN (
                SELECT sku_id, MAX(id) AS max_id
                FROM stock_ledger
                WHERE type = 'KITCHEN' 
                  AND store_id IN($store_id)
                  AND created BETWEEN '$startDatetime' AND '$endDatetime'
                GROUP BY sku_id
            ) latest ON sl1.id = latest.max_id
            WHERE sl1.type = 'KITCHEN' 
              AND sl1.store_id IN($store_id)
        ");
        
        $skus = $this->Inventory_sku->query("SELECT * FROM inventory_skus WHERE status=1");
        
        $skutransactions = [];
        if (!empty($sku_id)) {
            $skutransactions = $this->Stock_ledger->query("
                SELECT * FROM stock_ledger 
                WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
                AND type='KITCHEN' AND sku_id = $sku_id and store_id IN($store_id)
                ORDER BY id DESC
            ");
        }
        
        $this->set('stocklevel_daterange', date('m/d/Y', strtotime($stocklevel_startdate)) . ' - ' . date('m/d/Y', strtotime($stocklevel_enddate)));
        $this->set('skuledger_daterange', date('m/d/Y', strtotime($skuledger_startdate)) . ' - ' . date('m/d/Y', strtotime($skuledger_enddate)));

        $users=$this->Location->find('all',array('conditions'=>$conditions));
                
        $this->set(compact('users'));
    
        $this->set(compact('transactions', 'skus', 'skutransactions'));
    }

    public function kitchen_stock_levelexport() {
        $date_range = $_GET['sdate'] ?? '';
    
        $dates = explode(" - ", $date_range);
        if (count($dates) !== 2) {
            throw new BadRequestException('Invalid date range.');
        }
        $id = $this->Session->read('Auth.User.id');
        $username = $this->User->query("SELECT location_id FROM users WHERE id = $id");
        $store_id = $username[0]['users']['location_id'];
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Fetch stock ledger data
        $transactions = $this->Stock_ledger->query("
            SELECT sl1.sku_id,sl1.sku_price,sl1.sku_name,sl1.unit_name, sl1.actual_balance
            FROM stock_ledger sl1
            INNER JOIN (
                SELECT sku_id, MAX(id) AS max_id
                FROM stock_ledger
                WHERE type = 'KITCHEN' 
                  AND store_id = $store_id
                  AND created BETWEEN '$startDatetime' and  '$endDatetime'
                GROUP BY sku_id
            ) latest ON sl1.id = latest.max_id
            WHERE sl1.type = 'KITCHEN' 
              AND sl1.store_id = $store_id
        ");
        
        
        // Prepare for Excel export
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);
    
        if (PHP_SAPI == 'cli') {
            die('This example should only be run from a Web Browser');
        }
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()
            ->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("Stock Level Report")
            ->setSubject("Stock Report")
            ->setDescription("Exported stock level data.")
            ->setKeywords("stock excel")
            ->setCategory("Export File");
    
        // Header and formatting
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'STOCK LEVEL REPORT FROM '.$startdate.' TO '.$enddate);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:F1');
        $objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true)->setSize(14);
    
        // Column headers
        $headers = ['Sr No.', 'SKU Name', 'Unit Name', 'Price', 'Quantity', 'Value'];
        $col = 'A';
        foreach ($headers as $header) {
            $objPHPExcel->getActiveSheet()->setCellValue($col . '3', $header);
            $objPHPExcel->getActiveSheet()->getStyle($col . '3')->getFont()->setBold(true);
            $col++;
        }
    
        // Fill data
        $row = 4;
        $count = 1;
        foreach ($transactions as $txn) {
            $data = $txn['sl1'];
            $value = round($data['sku_price'] * $data['actual_balance'], 2);
    
            $objPHPExcel->getActiveSheet()
                ->setCellValue("A$row", $count)
                ->setCellValue("B$row", $data['sku_name'])
                ->setCellValue("C$row", $data['unit_name'])
                ->setCellValue("D$row", (float) $data['sku_price'])
                ->setCellValue("E$row", (float) $data['actual_balance'])
                ->setCellValue("F$row", $value);
    
            $row++;
            $count++;
        }
    
        // Finalize
        $objPHPExcel->getActiveSheet()->setTitle('Stock Level');
        $objPHPExcel->setActiveSheetIndex(0);
    
        // Output headers
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Stock_Level_Report.xls"');
        header('Cache-Control: max-age=0');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }
    
    public function semi_stock_level() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $stocklevel_startdate = $stocklevel_enddate = $skuledger_startdate = $skuledger_enddate = date('Y-m-d');
        $sku_id = null;
    
        if ($this->request->is(['post', 'put'])) {
            if (isset($this->request->data['submit_stocklevel'])) {
                $daterange = $this->request->data['stocklevel_daterange'] ?? '';
                $dates = explode(" - ", $daterange);
                if (count($dates) === 2) {
                    $stocklevel_startdate = date('Y-m-d', strtotime(trim($dates[0])));
                    $stocklevel_enddate = date('Y-m-d', strtotime(trim($dates[1])));
                }
                $startDatetime = $stocklevel_startdate . ' ' . shiftstart;
                $endDatetime   = date('Y-m-d', strtotime($stocklevel_enddate . ' +1 day')) . ' ' . shiftend;
            }
    
            if (isset($this->request->data['submit_skutransactions'])) {
                $daterange = $this->request->data['daterange'] ?? '';
                $dates = explode(" - ", $daterange);
                if (count($dates) === 2) {
                    $skuledger_startdate = date('Y-m-d', strtotime(trim($dates[0])));
                    $skuledger_enddate = date('Y-m-d', strtotime(trim($dates[1])));
                }
                $sku_id = $this->request->data['SkuLedger']['sku'] ?? null;
            }
            $startDatetime = $skuledger_startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($skuledger_enddate . ' +1 day')) . ' ' . shiftend;
            
        }
    
        $transactions = $this->Stock_ledger->query("
            SELECT * FROM stock_ledger 
            WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
            AND type='OUTLET' and item_type='SKU'
            ORDER BY id DESC
        ");
    
        $skus = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished WHERE status=1");
        
        $skutransactions = [];
        if (!empty($sku_id)) {
            $skutransactions = $this->Stock_ledger->query("
                SELECT * FROM stock_ledger 
                WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
                AND type='OUTLET' AND sku_id = $sku_id
                ORDER BY id DESC
            ");
        }
        
        $this->set('stocklevel_daterange', date('m/d/Y', strtotime($stocklevel_startdate)) . ' - ' . date('m/d/Y', strtotime($stocklevel_enddate)));
        $this->set('skuledger_daterange', date('m/d/Y', strtotime($skuledger_startdate)) . ' - ' . date('m/d/Y', strtotime($skuledger_enddate)));
    
        $this->set(compact('transactions', 'skus', 'skutransactions'));
    }

    public function semi_stock_levelexport() {
        $date_range = $_GET['sdate'] ?? '';
    
        $dates = explode(" - ", $date_range);
        if (count($dates) !== 2) {
            throw new BadRequestException('Invalid date range.');
        }
    
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
    
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        // Fetch stock ledger data
        $transactions = $this->Stock_ledger->query("
            SELECT * FROM stock_ledger 
            WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and type='OUTLET' and item_type='SKU'
            ORDER BY id DESC
        ");
    
        // Prepare for Excel export
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);
    
        if (PHP_SAPI == 'cli') {
            die('This example should only be run from a Web Browser');
        }
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()
            ->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("Stock Level Report")
            ->setSubject("Stock Report")
            ->setDescription("Exported stock level data.")
            ->setKeywords("stock excel")
            ->setCategory("Export File");
    
        // Header and formatting
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'STOCK LEVEL REPORT FROM '.$startdate.' TO '.$enddate);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:F1');
        $objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true)->setSize(14);
    
        // Column headers
        $headers = ['Sr No.', 'SKU Name', 'Unit Name', 'Price', 'Quantity', 'Value'];
        $col = 'A';
        foreach ($headers as $header) {
            $objPHPExcel->getActiveSheet()->setCellValue($col . '3', $header);
            $objPHPExcel->getActiveSheet()->getStyle($col . '3')->getFont()->setBold(true);
            $col++;
        }
    
        // Fill data
        $row = 4;
        $count = 1;
        foreach ($transactions as $txn) {
            $data = $txn['stock_ledger'];
            $value = round($data['sku_price'] * $data['quantity'], 2);
    
            $objPHPExcel->getActiveSheet()
                ->setCellValue("A$row", $count)
                ->setCellValue("B$row", $data['sku_name'])
                ->setCellValue("C$row", $data['unit_name'])
                ->setCellValue("D$row", (float) $data['sku_price'])
                ->setCellValue("E$row", (float) $data['quantity'])
                ->setCellValue("F$row", $value);
    
            $row++;
            $count++;
        }
    
        // Finalize
        $objPHPExcel->getActiveSheet()->setTitle('Stock Level');
        $objPHPExcel->setActiveSheetIndex(0);
    
        // Output headers
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Stock_Level_Report.xls"');
        header('Cache-Control: max-age=0');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    public function modifiers() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Catalog_modifier->query("SELECT * FROM catalog_modifier where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_modifier()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_modifier'));
            }
            
            $name = $this->data['User']['name'];
            $description = $this->data['User']['description'];
            $food_type = $this->data['User']['food_type'];
            $sort_order = $this->data['User']['sort_order'];
            $price = $this->data['User']['price'];
            $weight = $this->data['User']['weight'];
                
            $data['Catalog_modifier']=array(
                'name'=>$name,
                'description'=>$description,
                'food_type'=>$food_type,
                'sort_order'=>$sort_order,
                'price'=>$price,
                'weight'=>$weight,
                'sync'=>0,
                'local_sync'=>0
            );
        
            if($this->Catalog_modifier->saveAll($data['Catalog_modifier']))
            {
                $this->Flash->success(__('Modifier has been saved.'));
                return $this->redirect(array('action' => 'modifiers'));
            } else {
                $this->Flash->error(__('Modifier could not be saved. Please, try again.'));
            }
        }
        
    }
    
    public function modifier_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_modifier->id = $Id;
            $newStatus = $this->Catalog_modifier->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_modifier->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }   
    
    public function view_modifier()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $products = $this->Catalog_modifier->query("SELECT * FROM catalog_modifier where id=$id");
        $this->set(compact('products'));
        
    }
    
    public function modifiers_group() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->Catalog_modifier_group->query("SELECT * FROM catalog_modifier_group where  created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_modifiers_group()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_modifiers_group'));
            }
            if(isset($this->data['User']['is_default'])){
                $is_default=$this->data['User']['is_default'];
            }else{
                $is_default=0;
            }
            
            $name = $this->data['User']['name'];
            $description = $this->data['User']['description'];
            $group_type = $this->data['User']['group_type'];
            $sort_order = $this->data['User']['sort_order'];
            $min = $this->data['User']['min']?$this->data['User']['min']:0;
            $max = $this->data['User']['max']?$this->data['User']['max']:0;
                
            $data['Catalog_modifier_group']=array(
                'name'=>$name,
                'description'=>$description,
                'group_type'=>$group_type,
                'sort_order'=>$sort_order,
                'is_default'=>$is_default,
                'min'=>$min,
                'max'=>$max,
                'sync'=>0,
                'local_sync'=>0
            );
            
            if($this->Catalog_modifier_group->saveAll($data['Catalog_modifier_group']))
            {
                $last_id = $this->Catalog_modifier_group->getLastInsertID();
                $modifier_ids = $this->request->data['modifier_id'];
                
                if (!empty($modifier_ids)) {
                    $this->Inventory_linking->updateAll(
                        [
                            'Inventory_linking.sync' => 0,
                            'Inventory_linking.local_sync' => 0
                        ],
                        [
                            'Inventory_linking.parent_id' => $last_id,
                            'Inventory_linking.parent_type' => 'Modifier_group',
                            'Inventory_linking.component_type' => 'Modifier',
                        ]
                    );
                    
                    $linkData = [];
                
                    foreach ($modifier_ids as $modid) {
                        // Fetch modifier name safely
                        $modifier = $this->Catalog_modifier->find('first', [
                            'conditions' => ['Catalog_modifier.id' => $modid],
                            'fields' => ['name'],
                            'recursive' => -1
                        ]);
                
                        $mod_name = $modifier['Catalog_modifier']['name'] ?? '';
                        
                        $data['Inventory_linking']=array(
                            'parent_type'=>'Modifier_group',
                            'parent_id'=>$last_id,
                            'parent_name'=>$name,
                            'component_type'=>'Modifier',
                            'component_id'=>$modid,
                            'component_name'=>$mod_name,
                            'quantity'=>1,
                            'sync'=>0,
                            'local_sync'=>0
                        );
                        
                        // Save all rows
                        if ($this->Inventory_linking->saveAll($data['Inventory_linking'])) {
                            // Success
                        } else {
                            $this->Flash->error(__('Modifiers could not be grouped. Please try again.'));
                        }
                    }
                
                    
                }
                $this->Flash->success(__('Modifier Group has been saved.'));
                return $this->redirect(array('action' => 'modifiers_group'));
            } else {
                $this->Flash->error(__('Modifier Group could not be saved. Please, try again.'));
            }
        }
        
    }
    
    public function modifiers_group_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_modifier_group->id = $Id;
            $currentStatus = $this->Catalog_modifier_group->field('status');
            $newStatus = $currentStatus == 1 ? 0 : 1;
    
            // Begin transaction
            $this->Catalog_modifier_group->begin();
    
            // Try saving group status
            if ($this->Catalog_modifier_group->save(['status' => $newStatus, 'sync' => 0, 'local_sync' => 0])) {
    
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => $newStatus,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $Id,
                        'Inventory_linking.parent_type' => 'Modifier_group',
                        'Inventory_linking.component_type' => 'Modifier'
                    ]
                );
                
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => $newStatus,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.component_id' => $Id,
                        'Inventory_linking.parent_type' => 'Product',
                        'Inventory_linking.component_type' => 'Modifier_group'
                    ]
                );

                $this->Catalog_modifier_group->commit();
                echo json_encode(['status' => true]);
            } else {
                $this->Catalog_modifier_group->rollback();
                echo json_encode(['status' => false]);
            }
        }
    }

    
    public function view_modifiers_group()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $products = $this->Catalog_modifier_group->query("SELECT * FROM catalog_modifier_group where id=$id");
        $this->set(compact('products'));
        
        $modifier_linking = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Modifier_group' and component_type='Modifier' and status='1'");
        $this->set(compact('modifier_linking'));
        
    }
    
    public function fetch_modifiers_options()
    {
        $this->autoRender = false;
    
        $modifiers = $this->Catalog_modifier->find('all', [
            'conditions' => ['Catalog_modifier.status' => 1],
            'fields' => ['id', 'name', 'price'] // Include 'price'
        ]);
    
        $data = array_map(function ($item) {
            return $item['Catalog_modifier'];
        }, $modifiers);
    
        echo json_encode(['response_code' => 1, 'data' => $data]);
    }
    
    public function product_modifier()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Catalog_product->query("SELECT * FROM catalog_product where id=$id");
        $this->set(compact('products'));
        
        $modifiers = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Product' and component_type='Modifier_group' and status=1");
        $this->set(compact('modifiers'));
        
       if ($this->request->is(['post', 'put'])) {
            $data = $this->request->data['User'];
        
            $product_id = $data['id'] ?? null;
            $product_name = $data['name'] ?? '';
            $product_unit = $data['unit'] ?? '';
            $product_unit_name = $data['unit_name'] ?? '';
        
            if (empty($product_id)) {
                $this->Flash->error(__('Product Error'));
                return $this->redirect(['action' => 'product_modifier', '?' => ['id' => $product_id]]);
            }
        
            $selectedModifiers = [];
        
            // 1. Collect modifier IDs from PHP input fields (semi_id_X)
            $allModifiers = $this->Catalog_modifier_group->find('list', [
                'fields' => ['id'],
                'conditions' => ['status' => 1],
                'recursive' => -1
            ]);
        
            foreach ($allModifiers as $modifier_id => $val) {
                if (!empty($data['semi_id_' . $modifier_id])) {
                    $selectedModifiers[] = $data['semi_id_' . $modifier_id];
                }
            }
        
            // 2. Collect modifier IDs from JS-added inputs (select_sku_name[])
            $jsModifiers = $_POST['select_sku_name'] ?? [];
        
            // 3. Merge and deduplicate
            $modifier_ids = array_values(array_unique(array_merge($selectedModifiers, $jsModifiers)));
        
            // 4. Delete old mappings
            $this->Inventory_linking->updateAll(
                [
                    'Inventory_linking.status' => 0,
                    'Inventory_linking.sync' => 0,
                    'Inventory_linking.local_sync' => 0
                ],
                [
                    'Inventory_linking.parent_id' => $product_id,
                    'Inventory_linking.parent_type' => 'Product',
                    'Inventory_linking.component_type' => 'Modifier_group'
                ]
            );

            // 5. Build new mappings
            $linkData = [];
        
            foreach ($modifier_ids as $mod_id) {
                $mod = $this->Catalog_modifier_group->find('first', [
                    'conditions' => ['id' => $mod_id],
                    'fields' => ['id', 'name'],
                    'recursive' => -1
                ]);
        
                if (!$mod) continue;
        
                $linkData[] = [
                    'parent_type'=>'Product',
                    'parent_id'=>$product_id,
                    'parent_name'=>$product_name,
                    'component_type'=>'Modifier_group',
                    'component_id'=>$mod_id,
                    'component_name'=>$mod['Catalog_modifier_group']['name'],
                    'quantity'=>1,
                    'sync'=>0,
                    'local_sync'=>0
                ];
            }
        
            // 6. Save all
            if (!empty($linkData)) {
                if ($this->Inventory_linking->saveAll($linkData)) {
                    $this->Flash->success(__('Group modifiers have been saved successfully.'));
                } else {
                    $this->Flash->error(__('Some group modifiers could not be saved.'));
                }
            } else {
                $this->Flash->success(__('No modifiers selected. Existing mappings have been cleared.'));
            }
        
            return $this->redirect(['action' => 'product_list']);
        }

    }
 
    public function fetch_modifiers_group_options()
    {
        $this->autoRender = false;
    
        $linkedGroupIds = $this->Inventory_linking->find('list', [
            'fields' => ['Inventory_linking.parent_id', 'Inventory_linking.parent_id'],
            'conditions' => [
                'Inventory_linking.status' => 1,
                'Inventory_linking.parent_type' => 'Modifier_group',
                'Inventory_linking.component_type' => 'Modifier'
            ],
            'recursive' => -1
        ]);
    // print_r($linkedGroupIds);exit;
        $modifiers = $this->Catalog_modifier_group->find('all', [
            'conditions' => [
                'Catalog_modifier_group.status' => 1,
                'Catalog_modifier_group.id' => array_keys($linkedGroupIds)
            ],
            'fields' => ['Catalog_modifier_group.id', 'Catalog_modifier_group.name'],
            'order' => ['Catalog_modifier_group.name' => 'ASC']
        ]);
    
        $data = array_map(function ($item) {
            return $item['Catalog_modifier_group'];
        }, $modifiers);
    
        echo json_encode(['response_code' => 1, 'data' => $data]);
    }

    public function edit_modifiers() 
    {
        // Check if user is authenticated
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = 'users';
    
        // Get modifier ID from query string
        $id = $this->request->query('id') ?? null;
    
        if (!$id) {
            $this->Flash->error(__('Modifier ID not provided.'));
            return $this->redirect(['action' => 'modifiers']);
        }
    
        // Fetch modifier by ID
        $modifier = $this->Catalog_modifier->findById($id);
        if (!$modifier) {
            $this->Flash->error(__('Modifier not found.'));
            return $this->redirect(['action' => 'modifiers']);
        }
    
        // If form is submitted
        if ($this->request->is(['post', 'put'])) {
            $this->Catalog_modifier->id = $id;

            $data = $this->request->data;
            $data['Catalog_modifier']['sync'] = 0;
            $data['Catalog_modifier']['local_sync'] = 0;
    
            // Save updated data
            if ($this->Catalog_modifier->save($data)) {
                $this->Flash->success(__('Modifier has been updated successfully.'));
                return $this->redirect(['action' => 'modifiers']);
            } else {
                $this->Flash->error(__('Failed to update modifier. Please try again.'));
            }
        }
    
        // Pre-fill form with existing data
        $this->request->data = $modifier;
        $this->set(compact('modifier'));
    }
    
     public function edit_modifier_group()
    {
        $this->layout = 'users';
    
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $groupId = $this->request->query('id') ?? null;
    
        if (!$groupId) {
            $this->Flash->error(__('Invalid Modifier Group ID.'));
            return $this->redirect(['action' => 'modifiers_group']);
        }
    
        // Fetch current group details and modifiers
        $products = $this->Catalog_modifier_group->find('all', [
            'conditions' => ['Catalog_modifier_group.id' => $groupId],
            'limit' => 1
        ]);
        $modifier_linking = $this->Inventory_linking->find('all', [
            'conditions' => ['parent_id' => $groupId,'parent_type' => 'Modifier_group','component_type' => 'Modifier','status' => '1']
        ]);
        $this->set(compact('products', 'modifier_linking'));
    
        // On form submission
        if ($this->request->is(['post', 'put'])) {
            $data = $this->request->data;
            if($data['Catalog_modifier_group']['group_type']==0){
                $min=$data['Catalog_modifier_group']['min'];
                $max=$data['Catalog_modifier_group']['max'];
            }else{
                $min=0;
                $max=0;
            }
            $groupData = [
                'id' => $data['Catalog_modifier_group']['id'],
                'name' => $data['Catalog_modifier_group']['name'],
                'group_type' => $data['Catalog_modifier_group']['group_type'],
                'description' => $data['Catalog_modifier_group']['description'],
                'sort_order' => $data['Catalog_modifier_group']['sort_order'],
                'min' => $min,
                'max' => $max,
                'sync' => 0,
                'local_sync' => 0,
                'is_default' => $data['Catalog_modifier_group']['is_default']?$data['Catalog_modifier_group']['is_default']:0
            ];
    
            if ($this->Catalog_modifier_group->save($groupData)) {
    
                // Delete old modifier group linkings
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $groupId,
                        'Inventory_linking.parent_type' => 'Modifier_group',
                        'Inventory_linking.component_type' => 'Modifier'
                    ]
                );

                $modifierIds = $data['modifier_id'] ?? [];
                $modifierIds = array_unique(array_filter($modifierIds)); // also removes empty values
                $linkData = [];
    
                foreach ($modifierIds as $modId) {
                    if (empty($modId)) continue;
    
                    $mod = $this->Catalog_modifier->find('first', [
                        'conditions' => ['Catalog_modifier.id' => $modId],
                        'fields' => ['name'],
                        'recursive' => -1
                    ]);
                    $modName = $mod['Catalog_modifier']['name'] ?? '';
    
                    $linkData[] = [
                        'parent_type'=>'Modifier_group',
                        'parent_id'=>$groupId,
                        'parent_name'=>$groupData['name'],
                        'component_type'=>'Modifier',
                        'component_id'=>$modId,
                        'component_name'=>$modName,
                        'quantity'=>1,
                        'sync'=>0,
                        'local_sync'=>0
                    ];
                }
    
                if (!empty($linkData)) {
                    $this->Inventory_linking->saveAll($linkData);
                }
    
                $this->Flash->success(__('Modifier Group updated successfully.'));
                return $this->redirect(['action' => 'modifiers_group']);
            } else {
                $this->Flash->error(__('Failed to update Modifier Group.'));
            }
        }
    }
    
    public function modifier_recipe()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $products = $this->Catalog_modifier->query("SELECT * FROM catalog_modifier where id=$id order by name ASC");
        $this->set(compact('products'));
        
        $recipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Modifier' and component_type='Semifinished' and status=1");
        $skurecipes = $this->Inventory_linking->query("SELECT * FROM inventory_linking where parent_id=$id and parent_type='Modifier' and component_type='Sku' and status=1");
        $this->set(compact('recipes','skurecipes'));
        
        if ($this->request->is(array('post', 'put'))) {
            $product_id = $this->data['User']['id'];
            $product_name = $this->data['User']['name'];
            
            $selectedSemifinished=[];
            $semifinishedquantity=[];
            $semi_ids=[];
            $semi_quantities=[];
            $semifinisheds=$this->Inventory_semifinished->find('all',array('conditions'=>array('status'=>1)));
            foreach($semifinisheds as $semifinished){
                $semifinishedid = $semifinished['Inventory_semifinished']['id'];
                if (!empty($this->request->data['User']['semi_id_' . $semifinishedid])) {
                    $selectedSemifinished[] = $this->request->data['User']['semi_id_' . $semifinishedid];
                    $semifinishedquantity[]=$this->request->data['User']['semi_quantity_' . $semifinishedid];
                }
            }
            if(isset($_POST['select_semi_name'])){
                $semi_ids=$_POST['select_semi_name'];
                $semi_quantities=$_POST['semi_quantity'];
            }
            $mergedArraysemi = array_merge($selectedSemifinished, $semi_ids);
            $uniqueArraysemi = array_unique($mergedArraysemi);
            $semi_ids = array_values($uniqueArraysemi);
            
            $mergedArraysemi1 = array_merge($semifinishedquantity, $semi_quantities);
            $semi_quantities = array_values($mergedArraysemi1);

            if(isset($semi_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Modifier',
                        'Inventory_linking.component_type' => 'Semifinished'
                    ]
                );

                for ($i = 0; $i < count($semi_ids); $i++) {
                    $semi_id = $semi_ids[$i];
                    $semi_quantity = $semi_quantities[$i];
                    
                    $seminame=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semi_id)));
                    $semi_name=$seminame['Inventory_semifinished']['name'];
                    $semi_unit=$seminame['Inventory_semifinished']['unit'];
                    $semi_unit_name=$seminame['Inventory_semifinished']['unit_name'];
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Modifier',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'component_type'=>'Semifinished',
                        'component_id'=>$semi_id,
                        'component_name'=>$semi_name,
                        'quantity'=>$semi_quantity,
                        'component_unit'=>$semi_unit,
                        'component_unit_name'=>$semi_unit_name,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Semifinished mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $selectedSku=[];
            $skuquantity=[];
            $sku_ids=[];
            $sku_quantities=[];
            $skus=$this->Inventory_sku->find('all',array('conditions'=>array('status'=>1)));
            foreach($skus as $sku){
                $skuid = $sku['Inventory_sku']['id'];
                if (!empty($this->request->data['User']['sku_id_' . $skuid])) {
                    $selectedSku[] = $this->request->data['User']['sku_id_' . $skuid];
                    $skuquantity[]=$this->request->data['User']['sku_quantity_' . $skuid];
                }
            }
            if(isset($_POST['select_sku_name'])){
                $sku_ids=$_POST['select_sku_name'];
                $sku_quantities=$_POST['sku_quantity'];
            }
            $mergedArraysku = array_merge($selectedSku, $sku_ids);
            $uniqueArraysku = array_unique($mergedArraysku);
            $sku_ids = array_values($uniqueArraysku);
            
            $mergedArraysku1 = array_merge($skuquantity, $sku_quantities);
            $sku_quantities = array_values($mergedArraysku1);
            
            if(isset($sku_ids)){
                $this->Inventory_linking->updateAll(
                    [
                        'Inventory_linking.status' => 0,
                        'Inventory_linking.sync' => 0,
                        'Inventory_linking.local_sync' => 0
                    ],
                    [
                        'Inventory_linking.parent_id' => $product_id,
                        'Inventory_linking.parent_type' => 'Modifier',
                        'Inventory_linking.component_type' => 'Sku'
                    ]
                );

                for ($i = 0; $i < count($sku_ids); $i++) {
                    $sku_id = $sku_ids[$i];
                    $sku_quantity = $sku_quantities[$i];
                    
                    $skuname=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $sku_name=$skuname['Inventory_sku']['name'];
                    $sku_unit=$skuname['Inventory_sku']['unit'];
                    $sku_unit_name=$skuname['Inventory_sku']['unit_name'];
                    
                    $data['Inventory_linking']=array(
                        'parent_type'=>'Modifier',
                        'parent_id'=>$product_id,
                        'parent_name'=>$product_name,
                        'component_type'=>'Sku',
                        'component_id'=>$sku_id,
                        'component_name'=>$sku_name,
                        'quantity'=>$sku_quantity,
                        'component_unit'=>$sku_unit,
                        'component_unit_name'=>$sku_unit_name,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                    
                    
                    if($this->Inventory_linking->saveAll($data['Inventory_linking']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sku mapping could not be saved. Please, try again.'));
                    }
                }
            }
            
            $this->Flash->success(__('Recipe has been saved.'));
            return $this->redirect(array('action' => 'modifiers'));
        }
        
    }
    
    public function inv_category_list() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Inventory_category->find('all', array(
            'conditions' => array('created BETWEEN ? AND ?' => array($startDatetime, $endDatetime)
            ),
            'order' => array(
                'id' => 'DESC' // Order by the 'created' field in ascending order
            )
        ));
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function inv_subcategory_list() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $users = $this->Inventory_subcategory->query("SELECT *,(SELECT name FROM inventory_category where id=inventory_subcategory.cat_id) as cat_name FROM inventory_subcategory where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function inv_create_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'create_category'));
            }
            
            if(isset($_POST['subcat'])){
                $is_subcat=1;
            }else{
                $is_subcat=0;
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
            }
            // print_r($this->data);exit;
            
            $data['Inventory_category']=array(
                'name'=>$name,
                'is_subcategory'=>$is_subcat,
                'image'=>$filename,
                'sync'=>0,
                'local_sync'=>0
            );
            
            if($this->Inventory_category->saveAll($data['Inventory_category']))
            {
                $lastInsertedID = $this->Inventory_category->id;
                if(isset($_POST['subcat'])){
                    $subcats = $_POST['subcat'];
                    foreach ($subcats as $subcat) {
                        $data['Inventory_subcategory']=array(
                            'cat_id'=>$lastInsertedID,
                            'name'=>$subcat,
                            'sync'=>0,
                            'local_sync'=>0
                        );
                        
                        if($this->Inventory_subcategory->saveAll($data['Inventory_subcategory']))
                        {
                            
                        }else{
                            $this->Flash->error(__('Sub category could not be saved. Please, try again.'));
                        }
                    }
                }
                
                
                $this->Flash->success(__('Category has been saved.'));
                return $this->redirect(array('action' => 'inv_category_list'));
            } else {
                $this->Flash->error(__('Category could not be saved. Please, try again.'));
            }
        }
    }
    
    public function inv_edit_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories = $this->Inventory_category->query("SELECT * FROM inventory_category where id=$id");
        $this->set(compact('categories'));
        
        $subcategories=$this->Inventory_subcategory->query("SELECT * FROM inventory_subcategory where cat_id=$id and status=1");
        $this->set(compact('subcategories')); 
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'inv_edit_category?id='.$id));
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
                $this->Inventory_category->query("UPDATE `inventory_category` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
            }
            $this->Inventory_category->query("UPDATE `inventory_category` SET name='$name',sync = 0,local_sync=0 WHERE id=$id");
            
            $lastInsertedID = $id;
            if(isset($_POST['subcat'])){
                $subcats = $_POST['subcat'];
                foreach ($subcats as $subcat) {
                    $data['Inventory_subcategory']=array(
                        'cat_id'=>$lastInsertedID,
                        'name'=>$subcat,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                    
                    if($this->Inventory_subcategory->saveAll($data['Inventory_subcategory']))
                    {
                        
                    }else{
                        $this->Flash->error(__('Sub category could not be saved. Please, try again.'));
                    }
                }
            }
            
            $subcategorychk=$this->Inventory_subcategory->query("SELECT * FROM inventory_subcategory where cat_id=$id and status=1");
            if($subcategorychk){
                $this->Inventory_category->query("UPDATE `inventory_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$id");
            }else{
                $this->Inventory_category->query("UPDATE `inventory_category` SET is_subcategory='0',sync = 0,local_sync=0 WHERE id=$id");
            }
            
            $this->Flash->success(__('Category has been Updated.'));
            return $this->redirect(array('action' => 'inv_category_list'));
        
        }
    }
    
    public function inv_remove_subcategory() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Inventory_subcategory->id = $Id;
            if ($this->Inventory_subcategory->save(['status' => 0,'sync'=>0,'local_sync'=>0])) {
                
                $categoryid = $this->Inventory_subcategory->query("SELECT cat_id FROM inventory_subcategory where id=$Id");
                $cat_id=$categoryid['0']['inventory_subcategory']['cat_id'];
                
                $subcategorychk=$this->Inventory_subcategory->query("SELECT * FROM inventory_subcategory where cat_id=$cat_id and status=1");
                if($subcategorychk){
                    $this->Inventory_category->query("UPDATE inventory_category SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$cat_id");
                }else{
                    $this->Inventory_category->query("UPDATE inventory_category SET is_subcategory=0,sync = 0,local_sync=0 WHERE id=$cat_id");
                }
                
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function inv_create_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        if ($this->request->is(array('post', 'put'))) {
            $subcategoriesname=$_POST['subcat'];
            $categoryid = $this->data['User']['category'];
            if($categoryid==''){
                $this->Flash->error(__('Select Category'));
                return $this->redirect(array('action' => 'inv_create_subcategory'));
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
            }
            
            foreach($subcategoriesname as $subcategory){
                $data['Inventory_subcategory']=array(
                    'name'=>$subcategory,
                    'cat_id'=>$categoryid,
                    'image'=>$filename,
                    'sync'=>0,
                    'local_sync'=>0
                );
                
                if($this->Inventory_subcategory->saveAll($data['Inventory_subcategory']))
                {
                    $savechk=true;
                    
                }else{
                    $savechk=false;
                }
                
            }    
            
            if($savechk){
                $this->Inventory_category->query("UPDATE `inventory_category` SET is_subcategory='1',sync = 0,local_sync=0 WHERE id=$categoryid");
            
                    
                $this->Flash->success(__('Sub Category has been saved.'));
                return $this->redirect(array('action' => 'inv_subcategory_list'));
            } else {
                $this->Flash->error(__('Some sub Category could not be saved. Please, try again.'));
                return $this->redirect(array('action' => 'inv_subcategory_list'));
            }
        }
        
        $categories=$this->Inventory_category->find('all',array('conditions'=>array('status'=>1)));
        $this->set(compact('categories'));
    
    }
    
    public function inv_category_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Inventory_category->id = $Id;
            $newStatus = $this->Inventory_category->field('status') == 1 ? 0 : 1;
            
            if ($this->Inventory_category->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                $this->Inventory_subcategory->updateAll(
                    [
                        'Inventory_subcategory.status' => $newStatus,
                        'Inventory_subcategory.sync' => 0,
                        'Inventory_subcategory.local_sync' => 0
                    ],
                    ['Inventory_subcategory.cat_id' => $Id]
                );

                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function inv_subcategory_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Inventory_subcategory->id = $Id;
            $newStatus = $this->Inventory_subcategory->field('status') == 1 ? 0 : 1;
            
            if ($this->Inventory_subcategory->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function inv_view_category()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories = $this->Inventory_category->query("SELECT * FROM inventory_category where id=$id");
        $this->set(compact('categories'));
        
        $subcategories=$this->Inventory_subcategory->query("SELECT * FROM inventory_subcategory where cat_id=$id and status=1");
        $this->set(compact('subcategories')); 
    }
    
    public function inv_edit_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $subcategories=$this->Inventory_subcategory->query("SELECT *,(SELECT name FROM `inventory_category` WHERE id=inventory_subcategory.cat_id) as catname FROM inventory_subcategory where id=$id");
        $this->set(compact('subcategories')); 
        
        $categories=$this->Inventory_category->find('all',array('conditions'=>array('status'=>1),'order' => array(
                'name' => 'asc' // Order by the 'created' field in ascending order
            )));
        $this->set(compact('categories'));
        
        if ($this->request->is(array('post', 'put'))) {
            // print_r($this->data);exit;
            $id = $this->data['User']['id'];
            $name = $this->data['User']['name'];
            if($name==''){
                $this->Flash->error(__('The Name could not be Blank'));
                return $this->redirect(array('action' => 'inv_edit_subcategory?id='.$id));
            }
            
            $image=$this->data['User']['image'];
            if (!empty($image['name'])) {
                $uploadPath = WWW_ROOT . 'uploads' . DS . 'category_images' . DS;
                $file=basename(time().$image['name']);
                $file = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $file);
                $uploadFile = $uploadPath . $file;
                
                if (move_uploaded_file($image['tmp_name'], $uploadFile)) {
                    $filename=$file;
                }else{
                    $filename='';
                }
                $this->Inventory_subcategory->query("UPDATE `inventory_subcategory` SET image='$filename',sync = 0,local_sync=0 WHERE id=$id");
            }
            $category=$this->data['User']['category'];
        
            $categoryid = $this->Inventory_subcategory->query("SELECT cat_id FROM inventory_subcategory where id=$id");
            $cat_id=$categoryid['0']['inventory_subcategory']['cat_id'];
        
            $this->Inventory_subcategory->query("UPDATE `inventory_subcategory` SET name='$name',cat_id=$category,sync = 0,local_sync=0 WHERE id=$id");
            $this->Inventory_category->query("UPDATE `inventory_category` SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$category");
            
            $subcategorychk=$this->Inventory_subcategory->query("SELECT * FROM inventory_subcategory where cat_id=$cat_id and status=1");
            if($subcategorychk){
                $this->Inventory_category->query("UPDATE inventory_category SET is_subcategory=1,sync = 0,local_sync=0 WHERE id=$cat_id");
            }else{
                $this->Inventory_category->query("UPDATE inventory_category SET is_subcategory=0,sync = 0,local_sync=0 WHERE id=$cat_id");
            }
            
            $this->Flash->success(__('Sub Category has been Updated.'));
            return $this->redirect(array('action' => 'inv_subcategory_list'));
        
        }
    
    }
    
    public function inv_view_subcategory()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
        
        $categories=$this->Inventory_subcategory->query("SELECT *,(SELECT name FROM `inventory_category` WHERE id=inventory_subcategory.cat_id) as catname FROM inventory_subcategory where id=$id");
        $this->set(compact('categories')); 
    }
    
    public function indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        // Default date range
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate = date('m/d/Y');
    
        if ($this->request->is(['post', 'put'])) 
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Auth info
        $locationId = $this->Session->read('Auth.User.location_id');
        $userRole = $this->Session->read('Auth.User.role');
    
        // Base condition
        $conditions = "created BETWEEN '$startDatetime' and  '$endDatetime'";
        if ($userRole !== 'admin') {
            $conditions .= " AND warehouse_id = '$locationId'";
        }
    
        // Indents by status
        $submittedIndents = $this->Inventory_indent->query("
            SELECT * FROM inventory_indent 
            WHERE $conditions AND status = 1 
            ORDER BY id DESC
        ");
        $approvedIndents = $this->Inventory_indent->query("
            SELECT * FROM inventory_indent 
            WHERE $conditions AND status = 2 
            ORDER BY id DESC
        ");
        $processedIndents = $this->Inventory_indent->query("
            SELECT * FROM inventory_indent 
            WHERE $conditions AND status = 3 
            ORDER BY id DESC
        ");
    
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $newconditions='';
        if ($userRole !== 'admin') {
            $newconditions .= " warehouse_id = '$locationId' and";
        }
        $submitted_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status IN (1)
        ");
        $submitted_indent=$submitted_indents[0][0]['total'];
        
        $approved_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 2 
        ");
        $approved_indent=$approved_indents[0][0]['total'];
        
        $processed_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 3 
        ");
        $processed_indent=$processed_indents[0][0]['total'];
        
        $stockedin_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 4 
        ");
        $stockedin_indent=$stockedin_indents[0][0]['total'];
        $this->set(compact('submittedIndents', 'approvedIndents', 'processedIndents','submitted_indent','approved_indent','processed_indent','stockedin_indent'));
    }

    
    public function approve_indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $user = "
            SELECT 
                *
            FROM 
                inventory_indent_items
            WHERE
                inventory_indent_items.indent_id = $id
                AND inventory_indent_items.sku_quantity > 0
                AND inventory_indent_items.status = 1
            ORDER BY 
                inventory_indent_items.sku_name DESC
        ";
        
        $users = $this->Inventory_indent_items->query($user);
    
        $indentData = $this->Inventory_indent->find('first', [
            'conditions' => ['indent_id' => $id],
            'recursive' => -1
        ]);
    
        $selected_location_id = $indentData['Inventory_indent']['location_id'];
        $selected_expiry = $indentData['Inventory_indent']['expiry'];
    
        $this->set(compact('users', 'id', 'selected_location_id'));
    }
    
    public function update_approve_indent() 
    {
        $this->autoRender = false;
    
        $userId = $this->Session->read('Auth.User.id');
        $userName = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentId = $_POST['indent_id'];
            $expiry = $_POST['expiry'];
            $remarks = $_POST['remarks'];
            $vehicle = $_POST['vehicle'];
            $location_id = $_POST['location_id'] ?? null;
    
            $amount = 0;
            $success = false;
    
            foreach ($checkeddatas as $checkeddata) {
                $skuId = $checkeddata['id'];
               
               
                $price = floatval($checkeddata['price']);
                $approvedQty = $checkeddata['sku_quantity'];
                $item_type = isset($checkeddata['item_type']) ? $checkeddata['item_type'] : 'sku'; // default to sku
    
                // ✅ Fetch tax based on item type
                if ($item_type == 'semifinished') {
                    $product_taxes = $this->Inventory_semifinished_tax->query("
                        SELECT SUM(tax_percentage) AS total_tax 
                        FROM inventory_semifinished_tax 
                        WHERE product_id='$skuId' AND status = 1
                    ");
                } else {
                    $product_taxes = $this->Inventory_sku_tax->query("
                        SELECT SUM(tax_percentage) AS total_tax 
                        FROM inventory_sku_tax 
                        WHERE product_id='$skuId' AND status = 1
                    ");
                }
                $total_tax = isset($product_taxes[0][0]['total_tax']) ? round($product_taxes[0][0]['total_tax'], 2) : 0;
                $tax_value = round(($price * $approvedQty) * ($total_tax / 100), 2);
                $skuamount = round(($price * $approvedQty) + $tax_value, 2);
        
                // ✅ Update inventory_indent_items table (same table for both)
                $this->Inventory_indent_items->updateAll(
                    [
                        'approved_price' => $price,
                        'approved_quantity' => $approvedQty,
                        'approved_tax_value' => $tax_value,
                        'approved_amount' => $skuamount,
                        'sync' => 0,
                        'local_sync' => 0,
                        'status'=> 2
                    ],
                    [
                        'indent_id' => $indentId,
                        'sku_id' => $skuId,
                        'status' => 1
                    ]
                );
    
                $amount += $skuamount;
                $success = true;
            }
            
            if ($success) {
                $vehicle_value = $vehicle ? "'$vehicle'" : "''";
                $remarks_value = $remarks ? "'$remarks'" : "''";
                $expiry_value = $expiry ? "'$expiry'" : "''";
                $currentDate = date('Y-m-d H:i:s');
    
                $this->Inventory_indent->updateAll(
                    [
                        'approved_amount' => $amount,
                        'vehicle_no' => $vehicle_value,
                        'remarks' => $remarks_value,
                        'approved_selected_date' => $expiry_value,
                        'approved_date' => "'$currentDate'",
                        'status' => 2,
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['indent_id' => $indentId,
                        'status' => 1]
                );
    
                echo json_encode(['response_code' => 1, 'data' => 'Approved']);
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Indent items could not be updated.']);
            }
        }
    }

    
    public function process_indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'outlet', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    

        $user = "
            SELECT 
                *
            FROM 
                inventory_indent_items
            WHERE
                inventory_indent_items.indent_id = $id
                AND inventory_indent_items.sku_quantity > 0
                AND inventory_indent_items.status = 2
            ORDER BY 
                inventory_indent_items.sku_name DESC
        ";
        
        $users = $this->Inventory_indent_items->query($user);
    
        $indentData = $this->Inventory_indent->find('first', [
            'conditions' => ['indent_id' => $id],
            'recursive' => -1
        ]);
    
        $selected_location_id = $indentData['Inventory_indent']['location_id'];
        $selected_expiry = $indentData['Inventory_indent']['expiry'];
    
        $this->set(compact('users', 'id', 'selected_location_id'));
    }

    public function update_process_indent() 
    {
        $this->autoRender = false;
    
        $userId = $this->Session->read('Auth.User.id');
        $locationId = $this->Session->read('Auth.User.location_id');
        $userName = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentId = $_POST['indent_id'];
            $location_id = $_POST['location_id'] ?? null;
            
            $amount = 0;
            $success = false;
            
            do {
                $consignment_id = rand(1, 9);
                for ($i = 1; $i < 10; $i++) {
                    $consignment_id .= rand(0, 9);
                }
    
                $existing = $this->Inventory_indent->find('first', [
                    'conditions' => ['consignment_id' => $consignment_id],
                    'recursive' => -1
                ]);
            } while ($existing);
            
            $year = date('Y') + 501; // Example: 2025 + 573 = 2598 (you can adjust logic as per your 2526 example)

            // Step 2: Set prefix
            $prefix = 'TGI' . $year; // e.g., TGI2526
        
            // Step 3: Find latest code that starts with this year's prefix
            $latest = $this->Inventory_indent->find('first', [
                'fields' => ['serial_number'],
                'conditions' => ['Inventory_indent.serial_number LIKE' => $prefix . '%'],
                'order' => ['Inventory_indent.id' => 'DESC']
            ]);
        
            // Step 4: Calculate next number
            $nextNumber = 1;
            if (!empty($latest) && !empty($latest['Inventory_indent']['serial_number'])) {
                $lastCode = $latest['Inventory_indent']['serial_number']; // e.g., TGI252600057
                $numberPart = (int)substr($lastCode, strlen($prefix)); // Extract 00057 → 57
                $nextNumber = $numberPart + 1;
            }
        
            // Step 5: Final padded code
            $serial_number = $prefix . str_pad($nextNumber, 5, '0', STR_PAD_LEFT); // e.g., TGI252600058
        
            foreach ($checkeddatas as $checkeddata) {
                $skuId = $checkeddata['id'];
                $approvedQty = $checkeddata['sku_quantity'];
                $price = isset($checkeddata['price']) ? floatval($checkeddata['price']) : 0;
                $item_type = isset($checkeddata['item_type']) ? $checkeddata['item_type'] : 'sku'; // default to sku
    
                // ✅ Fetch tax based on item type
                if ($item_type == 'semifinished') {
                    $product_taxes = $this->Inventory_semifinished_tax->query("
                        SELECT SUM(tax_percentage) AS total_tax 
                        FROM inventory_semifinished_tax 
                        WHERE product_id='$skuId' AND status = 1
                    ");
                } else {
                    $product_taxes = $this->Inventory_sku_tax->query("
                        SELECT SUM(tax_percentage) AS total_tax 
                        FROM inventory_sku_tax 
                        WHERE product_id='$skuId' AND status = 1
                    ");
                }
                $total_tax = isset($product_taxes[0][0]['total_tax']) ? round($product_taxes[0][0]['total_tax'], 2) : 0;
                $tax_value = round(($price * $approvedQty) * ($total_tax / 100), 2);
                $skuamount = round(($price * $approvedQty) + $tax_value, 2);
    
                // Update each indent item with approved quantity and price
                $this->Inventory_indent_items->updateAll(
                    [
                        'processed_quantity' => $approvedQty,
                        'consignment_id' => $consignment_id,
                        'processed_tax_value' => $tax_value,
                        'processed_amount' => $skuamount,
                        'sync' => 0,
                        'local_sync' => 0,
                        'status' => 3
                    ],
                    [
                        'indent_id' => $indentId,
                        'sku_id' => $skuId,
                        'status' => 2
                    ]
                );
    
                $amount += ($skuamount);
                
                //stock ledger entry semifinished
                if ($item_type == 'semifinished') {
                    
                    $sku = $this->Inventory_semifinished->find('first', [
                        'conditions' => ['Inventory_semifinished.id' => $skuId],
                        'recursive' => -1
                    ]);
                    
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => ['sku_id' => $skuId,'type'=>'DC','item_type'=>'semifinished','store_id'=>$locationId],
                        'fields' => ['actual_balance'],
                        'order' => ['id DESC'],
                        'recursive' => -1
                    ]);
                    
                    $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                        ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                        : 0;
                    $newQuantity =  $ledger_prev_quantity-$approvedQty;
                    
                    $ledgerData['Stock_ledger'] = [
                            'store_id'        => $locationId,
                            'sku_id'          => $skuId,
                            'sku_name'        => $sku['Inventory_semifinished']['name'],
                            'sku_price'       => $sku['Inventory_semifinished']['price'],
                            'unit_id'         => $sku['Inventory_semifinished']['unit'],
                            'unit_name'       => $sku['Inventory_semifinished']['unit_name'],
                            'record_id'       => $indentId,
                            'record_type'     => 'process_indent',
                            'quantity'        => $approvedQty,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'debit',
                            'item_type'       => 'semifinished',
                            'type'            => 'DC',
                            'created'         => date('Y-m-d H:i:s'),
                            'sync'=>0,
                            'local_sync'=>0
                    ];
                    $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
                    
                    
                    $ingredients = $this->Inventory_linking->find('all', [
                        'conditions' => ['parent_id' => $skuId,'parent_type' => 'Semifinished','component_type' => 'Sku', 'status' => 1]
                    ]);
                    // print_r($ingredients);exit;
                    foreach ($ingredients as $ingredient) {
                        $sku_id = $ingredient['Inventory_linking']['component_id'];
                        $sku_quantity= $ingredient['Inventory_linking']['quantity']*$approvedQty;
                            
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $sku_id,'store_id' =>$locationId,'item_type'=>'SKU' ,'type' =>'DC' ],
                            'fields' => ['actual_balance'],
                            'order' => ['id DESC'],
                            'recursive' => -1
                        ]);
                        
                        $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                            ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                            : 0;
                        
                        $newQuantity = $ledger_prev_quantity-$sku_quantity;
                        
                        $sku = $this->Inventory_sku->find('first', [
                            'conditions' => ['Inventory_sku.id' => $sku_id],
                            'recursive' => -1
                        ]);
                        
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $locationId,
                                'sku_id'          => $ingredient['Inventory_linking']['component_id'],
                                'sku_name'        => $ingredient['Inventory_linking']['component_name'],
                                'sku_price'       => $sku['Inventory_sku']['price'],
                                'unit_id'         => $ingredient['Inventory_linking']['component_unit'],
                                'unit_name'       => $ingredient['Inventory_linking']['component_unit_name'],
                                'record_id'       => $indentId,
                                'record_type'     => 'process_indent',
                                'quantity'        => $sku_quantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'item_type'       => 'SKU',
                                'type'            => 'DC',
                                'created'         => date('Y-m-d H:i:s'),
                                'sync'=>0,
                                'local_sync'=>0
                        ];
                        if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                            $success=false;
                        }
                    }
                }else{
                    
                    $sku = $this->Inventory_sku->find('first', [
                        'conditions' => ['Inventory_sku.id' => $skuId],
                        'recursive' => -1
                    ]);
                    
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => ['sku_id' => $skuId,'store_id' =>$locationId,'item_type'=>'SKU' ,'type' =>'DC' ],
                        'fields' => ['actual_balance'],
                        'order' => ['id DESC'],
                        'recursive' => -1
                    ]);
                    
                    $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                        ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                        : 0;
                    
                    $newQuantity = $ledger_prev_quantity-$approvedQty;
                    
                    $ledgerData['Stock_ledger'] = [
                            'store_id'        => $locationId,
                            'sku_id'          => $sku['Inventory_sku']['id'],
                            'sku_name'        => $sku['Inventory_sku']['name'],
                            'sku_price'       => $sku['Inventory_sku']['price'],
                            'unit_id'         => $sku['Inventory_sku']['unit'],
                            'unit_name'       => $sku['Inventory_sku']['unit_name'],
                            'record_id'       => $indentId,
                            'record_type'     => 'process_indent',
                            'quantity'        => $approvedQty,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'debit',
                            'item_type'       => 'SKU',
                            'type'            => 'DC',
                            'created'         => date('Y-m-d H:i:s'),
                            'sync'=>0,
                            'local_sync'=>0
                    ];
                    if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                        $success=false;
                    }
                    
                }
                $success = true;
            }
    
            if ($success) {
                $currentDate = date('Y-m-d H:i:s');
    
                // Update the indent summary
                $this->Inventory_indent->updateAll(
                    [
                        'processed_amount' => $amount,
                        'processed_date' => "'$currentDate'",
                        'consignment_id' => $consignment_id,
                        'serial_number' => "'$serial_number'",
                        'status' => 3,
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['indent_id' => $indentId,
                        'status' => 2]
                );
        
                echo json_encode(['response_code' => 1, 'data' => 'Processed']);
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Indent items could not be updated.']);
            }
        } else {
            echo json_encode(['response_code' => 0, 'data' => 'Invalid request.']);
        }
    }

    public function edit_indent()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'outlet', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $role = $this->Session->read('Auth.User.role');
        $user_location = $this->Session->read('Auth.Location.id');
        
        // Fetch indent data
        $user = "SELECT *,
            (SELECT sku_quantity FROM inventory_indent_items 
             WHERE indent_id='$id' AND sku_id=inventory_skus.id) as quantity
            FROM inventory_skus 
            WHERE inventory_skus.status=1 
            ORDER BY inventory_skus.name DESC;";
        $users = $this->Inventory_sku->query($user);
    
        // Fetch existing indent record
        $indentData = $this->Inventory_indent->find('first', [
            'conditions' => ['indent_id' => $id],
            'recursive' => -1
        ]);
    
        $selected_location_id = $indentData['Inventory_indent']['location_id'];
        $selected_expiry = $indentData['Inventory_indent']['expiry'];
    
        $this->set(compact('users', 'id', 'locations', 'selected_location_id', 'selected_expiry'));
    }

    public function update_indent() 
    {
        $this->autoRender = false;
    
        $id = $this->Session->read('Auth.Location.id');
        $name = $this->Session->read('Auth.Location.name');
        
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentid = $_POST['indent_id'];
            $expiry = $_POST['expiry'];
            $location_id = isset($_POST['location_id']) ? $_POST['location_id'] : null;
            $location_name = '';
    
            // Optional: fetch location name if not passed from frontend
            if (!empty($location_id)) {
                $loc = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $location_id],
                    'fields' => ['Location.name'],
                    'recursive' => -1
                ]);
                $location_name = isset($loc['Location']['name']) ? $loc['Location']['name'] : '';
            }
    
            // Delete existing indent and items
            $this->Inventory_indent_items->query("UPDATE inventory_indent_items SET status=0,sync=0,local_sync=0 WHERE indent_id = " . (int)$indentid);
            $this->Inventory_indent->query("UPDATE FROM inventory_indent SET status=0,sync=0,local_sync=0 WHERE indent_id = " . (int)$indentid);
    
            $amount = 0;
            $chk = false;
    
            foreach ($checkeddatas as $checkeddata) {
                $skuid = $checkeddata['id'];
                $price = $checkeddata['price'];
                $sku_name = $checkeddata['sku_name'];
                $sku_brand = $checkeddata['sku_brand'];
                $unit_name = $checkeddata['unit_name'];
                $unit_id = $checkeddata['unit_id'];
                $quantity = $checkeddata['sku_quantity'];
    
                if (!empty($quantity)) {
                    $itemData = array(
                        'indent_id' => $indentid,
                        'sku_id' => $skuid,
                        'sku_name' => $sku_name,
                        'sku_brand' => $sku_brand,
                        'sku_unit' => $unit_id,
                        'sku_unit_name' => $unit_name,
                        'sku_price' => $price,
                        'sku_quantity' => $quantity,
                        'sync'=>0,
                        'local_sync'=>0
                    );
    
                    if ($this->Inventory_indent_items->saveAll($itemData)) {
                        $chk = true;
                    } else {
                        $chk = false;
                        $this->Flash->error(__('Internal indent could not be updated. Please, try again.'));
                    }
    
                    $productamount = $quantity * $price;
                    $amount += $productamount;
                }
            }
    
            if ($chk) {
                $indentData = array(
                    'indent_id' => $indentid,
                    'expiry' =>$expiry,
                    'created_by' => $id,
                    'created_by_name' => $name,
                    'location_id' => $location_id,
                    'location_name' => $location_name,
                    'total_amount' => $amount,
                    'is_updated' => 1,
                    'sync'=>0,
                    'local_sync'=>0
                );
    
                if ($this->Inventory_indent->saveAll($indentData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'Updated']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Internal indent could not be updated. Please, try again.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Internal indent items could not be updated. Please, try again.']);
            }
        }
    }
    
    
    public function grn()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        // Default date range
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate = date('m/d/Y');
    
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
    
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
    
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate = date('Y-m-d', strtotime($endDate));
        }
    
        // Auth info
        $locationId = $this->Session->read('Auth.User.location_id');
        $userRole = $this->Session->read('Auth.User.role');
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        // Base condition
        $conditions = "created BETWEEN '$startDatetime' and  '$endDatetime'";
        if ($userRole !== 'admin') {
            $conditions .= " AND warehouse_id = '$locationId'";
        }
    
        // Indents by status
        $submittedIndents = $this->Inventory_indent->query("
            SELECT * FROM inventory_indent 
            WHERE $conditions AND status = 3 
            ORDER BY id DESC
        ");
        $approvedIndents = $this->Inventory_indent->query("
            SELECT * FROM inventory_indent 
            WHERE $conditions AND status = 4
            ORDER BY id DESC
        ");
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
                
        $newconditions='';
        if ($userRole !== 'admin') {
            $newconditions .= " warehouse_id = '$locationId' and";
        }
        $submitted_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status IN (1)
        ");
        $submitted_indent=$submitted_indents[0][0]['total'];
        
        $approved_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 2 
        ");
        $approved_indent=$approved_indents[0][0]['total'];
        
        $processed_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 3 
        ");
        $processed_indent=$processed_indents[0][0]['total'];
        
        $stockedin_indents = $this->Inventory_indent->query("
            SELECT count(id) as total FROM inventory_indent 
            WHERE $newconditions status = 4 
        ");
        $stockedin_indent=$stockedin_indents[0][0]['total'];
        $this->set(compact('submitted_indent','approved_indent','processed_indent','stockedin_indent'));
        

        $this->set(compact('submittedIndents', 'approvedIndents'));
    }

    public function indent_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "login"; // or use 'ajax' or a dedicated PDF layout
    
        if ($this->request->is(['post', 'put'])) {
            $po_id = $this->request->data['Report']['poid'];
            // Secure: Use bound parameters
            $indents = $this->Inventory_indent->query(
                "SELECT *,(SELECT print_line1  FROM `locations`where id=inventory_indent.location_id) as print_line1
                ,(SELECT print_line2  FROM `locations`where id=inventory_indent.location_id) as print_line2
                ,(SELECT print_line3  FROM `locations`where id=inventory_indent.location_id) as print_line3
                ,(SELECT print_line1  FROM `locations`where id=inventory_indent.warehouse_id) as warehouse_print_line1
                ,(SELECT print_line2  FROM `locations`where id=inventory_indent.warehouse_id) as warehouse_print_line2
                ,(SELECT print_line3  FROM `locations`where id=inventory_indent.warehouse_id) as warehouse_print_line3
                FROM inventory_indent 
                 WHERE inventory_indent.indent_id = $po_id AND status != 0"
            );
    
            $items = $this->Inventory_indent_items->query(
                "SELECT * FROM inventory_indent_items 
                 WHERE indent_id = $po_id AND status != 0"
            );
            $location_id=$indents[0]['inventory_indent']['location_id'];
    
            // Get location details - default static for now
            $locationdetail = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location_id]
            ]);
    
            // Send data to the view
            $this->set(compact('po_id', 'indents', 'items', 'locationdetail'));
    
            // Optional: Force specific view if needed
            $this->render('indent_pdf'); // e.g., pdf_template.ctp
        }
    }
    
    public function stock_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate = date('m/d/Y');
    
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
    
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
    
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate = date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Session values
        $userRole = $this->Session->read('Auth.User.role');
        $locationId = $this->Session->read('Auth.User.location_id');
    
        // Build condition based on role
        $conditions = "created BETWEEN '$startDatetime' and  '$endDatetime'";
        if ($userRole !== 'admin') {
            $conditions .= " AND location_id = '$locationId'";
        }
    
        $users = $this->Inventory_damage->query("
            SELECT * FROM inventory_damage 
            WHERE $conditions and item_type='SKU' and type='Warehouse'
            ORDER BY id DESC
        ");
    
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users'));
    }
    
    public function damage_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['_id'];
    
            // Update user status
            $this->Inventory_damage->id = $userId;
            $newStatus = $this->Inventory_damage->field('status') == 1 ? 0 : 1;
            if ($this->Inventory_damage->save(['status' => $newStatus,'sync'=>0,'local_sync'=>0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function create_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        if ($this->Session->read('Auth.User.role') == 'admin') {
            $locations = $this->Location->find('all', ['conditions' => ['status' => 1,'type' => 'dc']]);
        } else {
            $location_id = $this->Session->read('Auth.User.location_id');
            $locations = $this->Location->find('all', [
                'conditions' => ['status' => 1, 'id' => $location_id,'type' => 'dc']
            ]);
        }
    
        $this->set(compact('locations'));
    
        $users = $this->Inventory_sku->find('all', [
            'conditions' => ['Inventory_sku.status' => 1],
            'order' => ['Inventory_sku.name ASC']
        ]);
        $this->set(compact('users'));
    }

    public function add_damage() 
    {
        $this->autoRender = false;
    
        if (!$this->Session->check('Auth.User.id')) {
            echo json_encode(['response_code' => 0, 'data' => 'User session expired.']);
            return;
        }
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData']) && isset($_POST['location_id'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $location_id = (int)$_POST['location_id'];
            $damage_date = $_POST['damage_date'];
            
            // Validate location
            $location = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location_id],
                'fields' => ['id', 'name'],
                'recursive' => -1
            ]);
    
            if (empty($location)) {
                echo json_encode(['response_code' => 0, 'data' => 'Invalid location selected.']);
                return;
            }
    
            // Generate unique indent_id
            do {
                // $txnid = '';
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
    
                $existing = $this->Inventory_damage->find('first', [
                    'conditions' => ['damage_id' => $txnid],
                    'recursive' => -1
                ]);
            } while ($existing);
    
            $amount = 0;
            $itemsSaved = true;
    
            foreach ($checkeddatas as $item) {
                $skuid = $item['id'];
                $price = $item['price'];
                $quantity = $item['sku_quantity'];
                
                $skuData = [
                    'location_id' => $location_id,
                    'location_name' => $location['Location']['name'],
                    'damage_id' => $txnid,
                    'item_id' => $skuid,
                    'item_name' => $item['sku_name'],
                    'item_category_id' => $item['cat_id'],
                    'item_category_name' => $item['cat_name'],
                    'unit_id' => $item['unit_id'],
                    'unit_name' => $item['unit_name'],
                    'item_price' => $price,
                    'quantity' => $quantity,
                    'amount' => $price*$quantity,
                    'sync'=>0,
                    'local_sync'=>0
                ];
                $this->Inventory_damage_item->create(); // ensure new row
                if (!$this->Inventory_damage_item->save($skuData)) {
                    $itemsSaved = false;
                    break;
                }
                
                $amount=$amount+($price*$quantity);
                
                $ledgerprevdetails = $this->Stock_ledger->find('first', [
                    'conditions' => ['sku_id' => $skuid,'type'=>'DC','item_type'=>'SKU','store_id'=>$location_id],
                    'fields' => ['actual_balance'],
                    'order' => ['id DESC'],
                    'recursive' => -1
                ]);
                
                $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                    ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                    : 0;
                
                $newQuantity = $ledger_prev_quantity - $quantity;
                // print_r($ledger_prev_quantity);exit;
                $ledgerData['Stock_ledger'] = [
                        'store_id'        => $location_id,
                        'sku_id'          => $skuid,
                        'sku_name'        => $item['sku_name'],
                        'sku_price'       => $price,
                        'unit_id'         => $item['unit_id'],
                        'unit_name'       => $item['unit_name'],
                        'record_id'       => $txnid,
                        'record_type'     => 'damage',
                        'quantity'        => $quantity,
                        'balance_stock'   => $newQuantity,
                        'actual_balance'  => $newQuantity,
                        'quantity_type'   => 'debit',
                        'type'            => 'DC',
                        'created'         => date('Y-m-d H:i:s'),
                        'sync'=>0,
                        'local_sync'=>0
                ];
                $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
                
            }
    
            if ($itemsSaved) {
                $damageData = [
                    'location_id' => $location_id,
                    'location_name' => $location['Location']['name'],
                    'damage_id' => $txnid,
                    'damage_date' => $damage_date,
                    'type' => 'Warehouse',
                    'item_type' => 'SKU',
                    'amount' => $amount,
                    'sync'=>0,
                    'local_sync'=>0
                ];
                
                $this->Inventory_damage->create();
                if ($this->Inventory_damage->save($damageData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'saved']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Failed to save damage master data.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Failed to save one or more items.']);
            }
        } else {
            echo json_encode(['response_code' => 0, 'data' => 'Invalid request. Missing data.']);
        }
    }

    public function view_damage()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Inventory_damage->query("SELECT * FROM inventory_damage where damage_id=$id and status=1");
        $this->set(compact('indents'));
        
        $items = $this->Inventory_damage_item->query("SELECT * FROM inventory_damage_items where damage_id=$id and status=1");
        
        $this->set(compact('items'));
        
        
    }
    
    public function edit_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $user_id = $this->Session->read('Auth.User.id');
        $role = $this->Session->read('Auth.User.role');
        $user_location = $this->Session->read('Auth.User.location_id');
    
        // Location dropdown data
        if ($role == 'admin') {
            $locations = $this->Location->find('list', ['conditions' => ['status' => 1,'type' => 'dc']]);
        } else {
            $locations = $this->Location->find('list', [
                'conditions' => ['status' => 1, 'id' => $user_location,'type' => 'dc']
            ]);
        }
    
        // Fetch indent data
        $user = "SELECT *,
            (SELECT quantity FROM inventory_damage_items
             WHERE damage_id='$id' AND item_id=inventory_skus.id and status=1) as quantity 
            FROM inventory_skus 
            WHERE inventory_skus.status=1 
            ORDER BY inventory_skus.name ASC";
       
        $users = $this->Inventory_sku->query($user);
         
        // Fetch existing indent record
        $indentData = $this->Inventory_damage->find('first', [
            'conditions' => ['damage_id' => $id,'status' => 1],
            'recursive' => -1
        ]);
        $selected_location_id = $indentData['Inventory_damage']['location_id'];
        $selected_date = $indentData['Inventory_damage']['damage_date'];
    
        $this->set(compact('users', 'id', 'locations', 'selected_location_id', 'selected_date'));
    }

    public function update_damage() 
    {
        $this->autoRender = false;
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentid = $_POST['indent_id'];
            $damage_date = $_POST['damage_date'];
            $location_id = isset($_POST['location_id']) ? $_POST['location_id'] : null;
            $location_name = '';
            
            // Optional: fetch location name if not passed from frontend
            if (!empty($location_id)) {
                $loc = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $location_id],
                    'fields' => ['Location.name'],
                    'recursive' => -1
                ]);
                $location_name = isset($loc['Location']['name']) ? $loc['Location']['name'] : '';
            }
            
            $items = $this->Inventory_damage_item->find('all', [
                'conditions' => [
                    'damage_id' => $indentid,
                    'status' => 1
                ],
                'recursive' => -1
            ]);
            
            foreach ($items as $lastdata) {
                $damagedata = $lastdata['Inventory_damage_item']; // Use the correct model alias
                $skuid       = $damagedata['item_id'];
                $price       = $damagedata['item_price'];
                $sku_name    = $damagedata['item_name'];
                $sku_brand   = isset($damagedata['sku_brand']) ? $damagedata['sku_brand'] : ''; // if available
                $unit_name   = $damagedata['unit_name'];
                $unit_id     = $damagedata['unit_id'];
                $cat_id      = $damagedata['item_category_id'];
                $cat_name    = $damagedata['item_category_name'];
                $quantity    = $damagedata['quantity'];
            
                if (!empty($quantity)) {
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => [
                            'sku_id' => $skuid,
                            'type' => 'DC',
                            'item_type'=>'SKU',
                            'store_id' => $location_id
                        ],
                        'fields' => ['actual_balance'],
                        'order' => ['id DESC'],
                        'recursive' => -1
                    ]);
            
                    $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                        ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                        : 0;
            
                    $newQuantity = $ledger_prev_quantity + $quantity;
            
                    $ledgerData = [
                        'Stock_ledger' => [
                            'store_id'        => $location_id,
                            'sku_id'          => $skuid,
                            'sku_name'        => $sku_name,
                            'sku_price'       => $price,
                            'unit_id'         => $unit_id,
                            'unit_name'       => $unit_name,
                            'record_id'       => $indentid,
                            'record_type'     => 'reverse_damage',
                            'quantity'        => $quantity,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'credit',
                            'type'            => 'DC',
                            'created'         => date('Y-m-d H:i:s'),
                            'sync'=>0,
                            'local_sync'=>0
                        ]
                    ];
            
                    $this->Stock_ledger->create(); // ensure a fresh entry
                    $this->Stock_ledger->save($ledgerData['Stock_ledger']);
                }
            }

    
            
            // Delete existing indent and items
            $this->Inventory_damage_item->query("UPDATE inventory_damage_items SET  status=0,sync = 0,local_sync=0 WHERE damage_id = " . (int)$indentid);
            $this->Inventory_damage->query("UPDATE inventory_damage SET  status=0,sync = 0,local_sync=0 WHERE damage_id = " . (int)$indentid);
    
            $amount = 0;
            $chk = false;
    
            foreach ($checkeddatas as $checkeddata) {
                $skuid = $checkeddata['id'];
                $price = $checkeddata['price'];
                $sku_name = $checkeddata['sku_name'];
                $sku_brand = $checkeddata['sku_brand'];
                $unit_name = $checkeddata['unit_name'];
                $unit_id = $checkeddata['unit_id'];
                $cat_id = $checkeddata['cat_id'];
                $cat_name = $checkeddata['cat_name'];
                $quantity = $checkeddata['sku_quantity'];
                
                if (!empty($quantity)) {
                    $itemData = array(
                        'location_id' => $location_id,
                        'location_name' => $location_name,
                        'damage_id' => $indentid,
                        'item_id' => $skuid,
                        'item_name' => $sku_name,
                        'item_category_id' => $cat_id,
                        'item_category_name' => $cat_name,
                        'unit_id' => $unit_id,
                        'unit_name' => $unit_name,
                        'item_price' => $price,
                        'quantity' => $quantity,
                        'amount' => $price*$quantity,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                    
                    if ($this->Inventory_damage_item->saveAll($itemData)) {
                        
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $skuid,'type'=>'DC','item_type'=>'SKU','store_id'=>$location_id],
                            'fields' => ['actual_balance'],
                            'order' => ['id DESC'],
                            'recursive' => -1
                        ]);
                        
                        $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                            ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                            : 0;
                        
                        $newQuantity = $ledger_prev_quantity - $quantity;
                        // print_r($ledger_prev_quantity);exit;
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $location_id,
                                'sku_id'          => $skuid,
                                'sku_name'        => $sku_name,
                                'sku_price'       => $price,
                                'unit_id'         => $unit_id,
                                'unit_name'       => $unit_name,
                                'record_id'       => $indentid,
                                'record_type'     => 'update_damage',
                                'quantity'        => $quantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'type'            => 'DC',
                                'created'         => date('Y-m-d H:i:s'),
                                'sync'=>0,
                                'local_sync'=>0
                        ];
                        $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
                        
                        $chk = true;
                    } else {
                        $chk = false;
                        $this->Flash->error(__('Damage could not be updated. Please, try again.'));
                    }
    
                    // $productamount = $quantity * $price;
                    // $amount += $productamount;
                    $amount += ($price*$quantity);
                }
            }
    
            if ($chk) {
                $indentData = array(
                    'location_id' => $location_id,
                    'location_name' => $location_name,
                    'damage_id' => $indentid,
                    'damage_date' => $damage_date,
                    'type' => 'Warehouse',
                    'item_type' => 'SKU',
                    'amount' => $amount,
                    'sync'=>0,
                    'local_sync'=>0
                );
    
                if ($this->Inventory_damage->saveAll($indentData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'Updated']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Damage could not be updated. Please, try again.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Damage items could not be updated. Please, try again.']);
            }
        }
    }
    
    public function semi_stock_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate = date('m/d/Y');
    
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
    
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
    
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate = date('Y-m-d', strtotime($endDate));
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        // Session values
        $userRole = $this->Session->read('Auth.User.role');
        $locationId = $this->Session->read('Auth.User.location_id');
    
        // Build condition based on role
        $conditions = "created BETWEEN '$startDatetime' and  '$endDatetime'";
        if ($userRole !== 'admin') {
            $conditions .= " AND location_id = '$locationId'";
        }
    
        $users = $this->Inventory_damage->query("
            SELECT * FROM inventory_damage 
            WHERE $conditions and item_type='semifinished' and type='Warehouse' and status=1
            ORDER BY id DESC
        ");
    
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('users'));
    }
    
    public function semi_damage_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $userId = $this->request->data['_id'];
    
            // Update user status
            $this->Inventory_damage->id = $userId;
            $newStatus = $this->Inventory_damage->field('status') == 1 ? 0 : 1;
            if ($this->Inventory_damage->save(['status' => $newStatus,'sync'=>0,'local_sync'=>0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function semi_create_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        if ($this->Session->read('Auth.User.role') == 'admin') {
            $locations = $this->Location->find('all', ['conditions' => ['status' => 1,'type' => 'dc']]);
        } else {
            $location_id = $this->Session->read('Auth.User.location_id');
            $locations = $this->Location->find('all', [
                'conditions' => ['status' => 1, 'id' => $location_id,'type' => 'dc']
            ]);
        }
    
        $this->set(compact('locations'));
    
        $users = $this->Inventory_semifinished->find('all', [
            'conditions' => ['Inventory_semifinished.status' => 1],
            'order' => ['Inventory_semifinished.name DESC']
        ]);
        $this->set(compact('users'));
    }

    public function semi_add_damage() 
    {
        $this->autoRender = false;
    
        if (!$this->Session->check('Auth.User.id')) {
            echo json_encode(['response_code' => 0, 'data' => 'User session expired.']);
            return;
        }
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData']) && isset($_POST['location_id'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $location_id = (int)$_POST['location_id'];
            $damage_date = $_POST['damage_date'];
            
            // Validate location
            $location = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location_id],
                'fields' => ['id', 'name'],
                'recursive' => -1
            ]);
    
            if (empty($location)) {
                echo json_encode(['response_code' => 0, 'data' => 'Invalid location selected.']);
                return;
            }
    
            // Generate unique indent_id
            do {
                // $txnid = '';
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
    
                $existing = $this->Inventory_damage->find('first', [
                    'conditions' => ['damage_id' => $txnid],
                    'recursive' => -1
                ]);
            } while ($existing);
    
            $amount = 0;
            $itemsSaved = true;
    
            foreach ($checkeddatas as $item) {
                $skuid = $item['id'];
                $price = $item['price'];
                $quantity = $item['sku_quantity'];
                
                $skuData = [
                    'location_id' => $location_id,
                    'location_name' => $location['Location']['name'],
                    'damage_id' => $txnid,
                    'item_id' => $skuid,
                    'item_name' => $item['sku_name'],
                    'item_category_id' => $item['cat_id'],
                    'item_category_name' => $item['cat_name'],
                    'unit_id' => $item['unit_id'],
                    'unit_name' => $item['unit_name'],
                    'item_price' => $price,
                    'quantity' => $quantity,
                    'amount' => $price*$quantity,
                    'sync'=>0,
                    'local_sync'=>0
                ];
                $this->Inventory_damage_item->create(); // ensure new row
                if (!$this->Inventory_damage_item->save($skuData)) {
                    $itemsSaved = false;
                    break;
                }
                
                $amount=$amount+($price*$quantity);
                
                $ledgerprevdetails = $this->Stock_ledger->find('first', [
                    'conditions' => ['sku_id' => $skuid,'type'=>'DC','item_type'=>'semifinished','store_id'=>$location_id],
                    'fields' => ['actual_balance'],
                    'order' => ['id DESC'],
                    'recursive' => -1
                ]);
                
                $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                    ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                    : 0;
                
                $newQuantity = $ledger_prev_quantity - $quantity;
                // print_r($ledger_prev_quantity);exit;
                $ledgerData['Stock_ledger'] = [
                        'store_id'        => $location_id,
                        'sku_id'          => $skuid,
                        'sku_name'        => $item['sku_name'],
                        'sku_price'       => $price,
                        'unit_id'         => $item['unit_id'],
                        'unit_name'       => $item['unit_name'],
                        'record_id'       => $txnid,
                        'record_type'     => 'damage',
                        'quantity'        => $quantity,
                        'balance_stock'   => $newQuantity,
                        'actual_balance'  => $newQuantity,
                        'quantity_type'   => 'debit',
                        'type'            => 'DC',
                        'item_type'       => 'semifinished',
                        'created'         => date('Y-m-d H:i:s'),
                        'sync'=>0,
                        'local_sync'=>0
                ];
                $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
                
            }
    
            if ($itemsSaved) {
                $damageData = [
                    'location_id' => $location_id,
                    'location_name' => $location['Location']['name'],
                    'damage_id' => $txnid,
                    'damage_date' => $damage_date,
                    'type' => 'Warehouse',
                    'item_type' => 'semifinished',
                    'amount' => $amount
                ];
                
                $this->Inventory_damage->create();
                if ($this->Inventory_damage->save($damageData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'saved']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Failed to save damage master data.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Failed to save one or more items.']);
            }
        } else {
            echo json_encode(['response_code' => 0, 'data' => 'Invalid request. Missing data.']);
        }
    }

    public function semi_view_damage()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Inventory_damage->query("SELECT * FROM inventory_damage where damage_id=$id and status=1");
        $this->set(compact('indents'));
        
        $items = $this->Inventory_damage_item->query("SELECT * FROM inventory_damage_items where damage_id=$id and status=1");
        
        $this->set(compact('items'));
        
        
    }
    
    public function semi_edit_damage()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
        $id = $_REQUEST['id'];
    
        $user_id = $this->Session->read('Auth.User.id');
        $role = $this->Session->read('Auth.User.role');
        $user_location = $this->Session->read('Auth.User.location_id');
    
        // Location dropdown data
        if ($role == 'admin') {
            $locations = $this->Location->find('list', ['conditions' => ['status' => 1,'type' => 'dc']]);
        } else {
            $locations = $this->Location->find('list', [
                'conditions' => ['status' => 1, 'id' => $user_location,'type' => 'dc']
            ]);
        }
    
        // Fetch indent data
        $user = "SELECT *,
            (SELECT quantity FROM inventory_damage_items
             WHERE damage_id='$id' AND item_id=inventory_semifinished.id and status=1) as quantity 
            FROM inventory_semifinished 
            WHERE inventory_semifinished.status=1 
            ORDER BY inventory_semifinished.name DESC";
       
        $users = $this->Inventory_semifinished->query($user);
         
        // Fetch existing indent record
        $indentData = $this->Inventory_damage->find('first', [
            'conditions' => ['damage_id' => $id,'status' => 1],
            'recursive' => -1
        ]);
        $selected_location_id = $indentData['Inventory_damage']['location_id'];
        $selected_date = $indentData['Inventory_damage']['damage_date'];
    
        $this->set(compact('users', 'id', 'locations', 'selected_location_id', 'selected_date'));
    }

    public function semi_update_damage() 
    {
        $this->autoRender = false;
    
        $id = $this->Session->read('Auth.User.id');
        $name = $this->Session->read('Auth.User.name');
    
        if (isset($_POST['checkedData'])) {
            $checkeddatas = json_decode($_POST['checkedData'], true);
            $indentid = $_POST['indent_id'];
            $damage_date = $_POST['damage_date'];
            $location_id = isset($_POST['location_id']) ? $_POST['location_id'] : null;
            $location_name = '';
            
            // Optional: fetch location name if not passed from frontend
            if (!empty($location_id)) {
                $loc = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $location_id],
                    'fields' => ['Location.name'],
                    'recursive' => -1
                ]);
                $location_name = isset($loc['Location']['name']) ? $loc['Location']['name'] : '';
            }
            
            $items = $this->Inventory_damage_item->find('all', [
                'conditions' => [
                    'damage_id' => $indentid,
                    'status' => 1
                ],
                'recursive' => -1
            ]);
            
            foreach ($items as $lastdata) {
                $damagedata = $lastdata['Inventory_damage_item']; // Use the correct model alias
                $skuid       = $damagedata['item_id'];
                $price       = $damagedata['item_price'];
                $sku_name    = $damagedata['item_name'];
                $sku_brand   = isset($damagedata['sku_brand']) ? $damagedata['sku_brand'] : ''; // if available
                $unit_name   = $damagedata['unit_name'];
                $unit_id     = $damagedata['unit_id'];
                $cat_id      = $damagedata['item_category_id'];
                $cat_name    = $damagedata['item_category_name'];
                $quantity    = $damagedata['quantity'];
            
                if (!empty($quantity)) {
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => [
                            'sku_id' => $skuid,
                            'item_type' => 'semifinished',
                            'type' => 'DC',
                            'store_id' => $location_id
                        ],
                        'fields' => ['actual_balance'],
                        'order' => ['id DESC'],
                        'recursive' => -1
                    ]);
            
                    $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                        ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                        : 0;
            
                    $newQuantity = $ledger_prev_quantity + $quantity;
            
                    $ledgerData = [
                        'Stock_ledger' => [
                            'store_id'        => $location_id,
                            'sku_id'          => $skuid,
                            'sku_name'        => $sku_name,
                            'sku_price'       => $price,
                            'unit_id'         => $unit_id,
                            'unit_name'       => $unit_name,
                            'record_id'       => $indentid,
                            'record_type'     => 'reverse_damage',
                            'quantity'        => $quantity,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'credit',
                            'item_type'       => 'semifinished',
                            'type'            => 'DC',
                            'created'         => date('Y-m-d H:i:s'),
                            'sync'=>0,
                            'local_sync'=>0
                        ]
                    ];
            
                    $this->Stock_ledger->create(); // ensure a fresh entry
                    $this->Stock_ledger->save($ledgerData['Stock_ledger']);
                }
            }

    
            
            // Delete existing indent and items
            $this->Inventory_damage_item->query("UPDATE inventory_damage_items SET  status=0,sync = 0,local_sync=0 WHERE damage_id = " . (int)$indentid);
            $this->Inventory_damage->query("UPDATE inventory_damage SET  status=0,sync = 0,local_sync=0 WHERE damage_id = " . (int)$indentid);
    
            $amount = 0;
            $chk = false;
    
            foreach ($checkeddatas as $checkeddata) {
                $skuid = $checkeddata['id'];
                $price = $checkeddata['price'];
                $sku_name = $checkeddata['sku_name'];
                $sku_brand = $checkeddata['sku_brand'];
                $unit_name = $checkeddata['unit_name'];
                $unit_id = $checkeddata['unit_id'];
                $cat_id = $checkeddata['cat_id'];
                $cat_name = $checkeddata['cat_name'];
                $quantity = $checkeddata['sku_quantity'];
                
                if (!empty($quantity)) {
                    $itemData = array(
                        'location_id' => $location_id,
                        'location_name' => $location_name,
                        'damage_id' => $indentid,
                        'item_id' => $skuid,
                        'item_name' => $sku_name,
                        'item_category_id' => $cat_id,
                        'item_category_name' => $cat_name,
                        'unit_id' => $unit_id,
                        'unit_name' => $unit_name,
                        'item_price' => $price,
                        'quantity' => $quantity,
                        'amount' => $price*$quantity,
                        'sync'=>0,
                        'local_sync'=>0
                    );
                    
                    if ($this->Inventory_damage_item->saveAll($itemData)) {
                        
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $skuid,'type'=>'DC','item_type'=>'semifinished','store_id'=>$location_id],
                            'fields' => ['actual_balance'],
                            'order' => ['id DESC'],
                            'recursive' => -1
                        ]);
                        
                        $ledger_prev_quantity = !empty($ledgerprevdetails['Stock_ledger']['actual_balance']) 
                            ? $ledgerprevdetails['Stock_ledger']['actual_balance'] 
                            : 0;
                        
                        $newQuantity = $ledger_prev_quantity - $quantity;
                        // print_r($ledger_prev_quantity);exit;
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $location_id,
                                'sku_id'          => $skuid,
                                'sku_name'        => $sku_name,
                                'sku_price'       => $price,
                                'unit_id'         => $unit_id,
                                'unit_name'       => $unit_name,
                                'record_id'       => $indentid,
                                'record_type'     => 'update_damage',
                                'quantity'        => $quantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'type'            => 'DC',
                                'item_type'       => 'semifinished',
                                'created'         => date('Y-m-d H:i:s'),
                                'sync'=>0,
                                'local_sync'=>0
                        ];
                        $this->Stock_ledger->saveAll($ledgerData['Stock_ledger']);
                        
                        $chk = true;
                    } else {
                        $chk = false;
                        $this->Flash->error(__('Damage could not be updated. Please, try again.'));
                    }
    
                    // $productamount = $quantity * $price;
                    // $amount += $productamount;
                    $amount += ($price*$quantity);
                }
            }
    
            if ($chk) {
                $indentData = array(
                    'location_id' => $location_id,
                    'location_name' => $location_name,
                    'damage_id' => $indentid,
                    'damage_date' => $damage_date,
                    'type' => 'Warehouse',
                    'item_type' => 'semifinished',
                    'amount' => $amount,
                    'sync'=>0,
                    'local_sync'=>0
                );
    
                if ($this->Inventory_damage->saveAll($indentData)) {
                    echo json_encode(['response_code' => 1, 'data' => 'Updated']);
                } else {
                    echo json_encode(['response_code' => 0, 'data' => 'Damage could not be updated. Please, try again.']);
                }
            } else {
                echo json_encode(['response_code' => 0, 'data' => 'Damage items could not be updated. Please, try again.']);
            }
        }
    }
    
    public function auditstock()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        // Default date range (last 30 days)
        $startDate = date('m/d/Y', strtotime('-30 days'));
        $endDate = date('m/d/Y');
        
        // If form submitted, get date range
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        } 
    
        // Auth User Info
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? 0;
    
        // Base conditions
        $baseConditions = [
            // 'Audit_stock.auditto >=' => $startdate,
            'auditto <=' => $enddate
        ];
    
        // Location filter for non-admins
        if ($userRole !== 'admin') {
            // $baseConditions['Audit_stock.location_id'] = $userLocationId;
        }
        
        // $sdate=$startdate.' 00:00:01';
        // $edate=$enddate.' 23:59:59';
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
       
        $preparedStocks = $this->Audit_stock->find('all', [
            'conditions' => [
                'Audit_stock.status' => 1,
                'Audit_stock.updateon BETWEEN ? AND ?' => [$startDatetime, $endDatetime],
                'Audit_stock.item_type' => 'SKU',
                'Audit_stock.type' => 'DC'
            ],
            'fields' => ['Audit_stock.*'], // Ensure ID is included
            'order' => ['Audit_stock.id' => 'DESC'],
            'recursive' => 1
        ]);
        

    
        // Pass to view
        $daterangeFormatted = $startDate . ' - ' . $endDate;
        $this->set(compact('daterangeFormatted', 'preparedStocks'));
    }

    public function create_audit_stock()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $userId = $this->Session->read('Auth.User.id');
        $today = date("Y-m-d");
        $currentTime = date("H:i");
        $this->set(compact('today', 'currentTime'));
    
        // Load SKU list
        $skus = $this->Inventory_sku->query("SELECT * FROM inventory_skus WHERE status = 1 ORDER BY name ASC");
        $this->set(compact('skus'));
    }
    
    public function add_auditstock()
    {
        $data = $this->request->data;
    
        $remarks = trim($data['remarks']);
        $auditDate = $data['audit_date'] ?? $today;
        $auditTime = $data['audit_time'] ?? $currentTime;
        $createdTime = date('Y-m-d H:i:s');
    
        $authUser = $this->Session->read('Auth.User');
        $storeId = $authUser['location_id'] ?? 0;
    
        $loc = $this->Location->find('first', [
            'conditions' => ['Location.id' => $storeId],
            'fields' => ['Location.name'],
            'recursive' => -1
        ]);
        $store_name = $loc['Location']['name'] ?? '';
    
        // Generate unique audit ID
        do {
            $pos_audit_id = substr(preg_replace('/\D/', '', sha1(uniqid() . rand())), 0, 12);
            if ($pos_audit_id[0] == '0') {
                $pos_audit_id[0] = rand(1,9);
            }
            $exists = $this->Audit_stock->find('count', [
                'conditions' => ['Audit_stock.pos_audit_id' => $pos_audit_id],
                'recursive' => -1
            ]);
        } while ($exists > 0);
    
        $header = [
            'pos_audit_id' => $pos_audit_id,
            'store_id' => $storeId,
            'store_name' => $store_name,
            'remarks' => $remarks,
            'status' => 1,
            'select_all' => 0,
            'updateon' => $createdTime
        ];
    
        // ✅ NEW: Read JSON data
        $checkedData = json_decode($data['checkedData'], true);
    
        $auditto = $auditDate . ' ' . $auditTime . ':00';
        $nowServer = date('Y-m-d H:i:s');
        if (strtotime($auditto) < strtotime($nowServer)) {
            $auditto = $nowServer;
        }
    
        foreach ($checkedData as $item) {
    
            $skuId = $item['id'];
            $qty = floatval($item['quantity']);
            $skuName = $item['sku_name'];
            $unitName = $item['unit_name'];
            $unitId = (int)$item['unit_id'];
            $sku_price = $item['price'];
    
            // Get last audit
            $lastAudit = $this->Audit_stock_items->find('first', [
                'conditions' => ['sku_id' => $skuId, 'item_type' => 'sku', 'type' => 'DC', 'status' => 1, 'store_id' => $storeId],
                'order' => ['id DESC'],
                'recursive' => -1
            ]);
    
            $openingstock = 0;
            $auditfrom = '2025-01-01 00:00:01';
            if (!empty($lastAudit)) {
                $openingstock = floatval($lastAudit['Audit_stock_items']['physicalstock']);
                $auditfrom = $lastAudit['Audit_stock_items']['auditto'];
            }
    
            $var = $this->Stock_ledger->query("
                SELECT 
                    SUM(CASE WHEN quantity_type='credit' THEN quantity ELSE 0 END) AS purchase,
                    SUM(CASE WHEN record_type IN ('stockout','stockout_modifier','process_indent','stock_transfer_to_kitchen') THEN quantity ELSE 0 END) AS consumption,
                    (
                        SUM(CASE WHEN record_type IN ('damage','update_damage') AND quantity_type='debit' THEN quantity ELSE 0 END)
                        -
                        SUM(CASE WHEN record_type='reverse_damage' AND quantity_type='credit' THEN quantity ELSE 0 END)
                    ) AS damage
                FROM stock_ledger
                WHERE store_id='$storeId' AND item_type='SKU' AND sku_id=$skuId 
                AND type='DC' AND created BETWEEN '$auditfrom' AND '$auditto'
            ")[0][0];
    
            $purchase = floatval($var['purchase'] ?? 0);
            $consumption = floatval($var['consumption'] ?? 0);
            $damage = floatval($var['damage'] ?? 0);
    
            $variance = round($qty - $openingstock - $purchase + $consumption + $damage, 2);
            $closingstock = round($openingstock + $purchase - $consumption - $damage, 2);
    
            $this->Audit_stock_items->create();
            $this->Audit_stock_items->save([
                'sku_id' => $skuId,
                'pos_audit_id' => $pos_audit_id,
                'store_id' => $storeId,
                'sku_name' => $skuName,
                'sku_unit' => $unitId,
                'sku_unit_name' => $unitName,
                'sku_price'=>$sku_price,
                'openingstock' => $openingstock,
                'closingstock' => $closingstock,
                'physicalstock' => $qty,
                'variance' => $variance,
                'purchased' => $purchase,
                'consumption' => $consumption,
                'damage' => $damage,
                'auditfrom' => $auditfrom,
                'auditto' => $auditto,
                'remarks' => $remarks,
                'status' => 1,
                'created' => $createdTime,
                'modified' => $createdTime,
                'sync'=>0,
                'local_sync'=>0
            ]);
    
            // Ledger insert
            $this->Stock_ledger->create();
            $this->Stock_ledger->save([
                'store_id' => $storeId,
                'sku_id' => $skuId,
                'sku_name' => $skuName,
                'sku_price'=>$sku_price,
                'unit_id' => $unitId,
                'unit_name' => $unitName,
                'record_id' => $pos_audit_id,
                'record_type' => 'audit_stock',
                'quantity' => 0,
                'balance_stock' => 0,
                'variance' => $variance,
                'actual_balance' => $qty,
                'variance_type' => 'audit',
                'variance_id' => $pos_audit_id,
                'type' => 'DC',
                'quantity_type' => 'audit',
                'created' => $auditto,
                'modified' => $createdTime,
                'sync'=>0,
                'local_sync'=>0
            ]);
        }
    
        // Save header
        $this->Audit_stock->create();
        if ($this->Audit_stock->save($header)) {
            echo "success";
            exit;
        } else {
            echo "failed";
            exit;
        }
    }
    
    public function view_audit()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Audit_stock->query("SELECT * FROM pos_auditstock where pos_audit_id=$id");
        $this->set(compact('indents'));
        
        $items = $this->Audit_stock_items->query("SELECT * FROM pos_auditstock_items where pos_audit_id=$id and status=1");
        
        $this->set(compact('items'));
        
        
    }
    
    public function semi_auditstock()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        // Default date range (last 30 days)
        $startDate = date('m/d/Y', strtotime('-7 days'));
        $endDate = date('m/d/Y');
        
        // If form submitted, get date range
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        } 
    
        // Auth User Info
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? 0;
    
        // Base conditions
        $baseConditions = [
            // 'Audit_stock.auditto >=' => $startdate,
            'auditto <=' => $enddate
        ];
    
        // Location filter for non-admins
        if ($userRole !== 'admin') {
            // $baseConditions['Audit_stock.location_id'] = $userLocationId;
        }
        
        // $sdate=$startdate.' 00:00:01';
        // $edate=$enddate.' 23:59:59';
       
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
       
        $preparedStocks = $this->Audit_stock->find('all', [
            'conditions' => [
                'Audit_stock.status' => 1,
                'Audit_stock.updateon BETWEEN ? AND ?' => [$startDatetime, $endDatetime],
                'Audit_stock.item_type' => 'Semifinished',
                'Audit_stock.type' => 'DC'
            ],
            'fields' => ['Audit_stock.*'], // Ensure ID is included
            'order' => ['Audit_stock.id' => 'DESC'],
            'recursive' => 1
        ]);



    
        // Pass to view
        $daterangeFormatted = $startDate . ' - ' . $endDate;
        $this->set(compact('daterangeFormatted', 'startdate', 'enddate', 'preparedStocks'));
    }

    public function semi_create_audit_stock()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $userId = $this->Session->read('Auth.User.id');
        $today = date("Y-m-d");
        $currentTime = date("H:i");
        $this->set(compact('today', 'currentTime'));
    
        // Load SKU list
        $skus = $this->Inventory_semifinished->query("SELECT * FROM inventory_semifinished WHERE status = 1 ORDER BY name ASC");
        $this->set(compact('skus'));
    
        if ($this->request->is(['post', 'put'])) {
            $data = $this->request->data;
    
            $remarks = trim($data['remarks']);
            $auditDate = $data['audit_date'] ?? $today;
            $auditTime = $data['audit_time'] ?? $currentTime;
            $submitAll = $data['submit_all_items'] ?? 'no';
            $createdTime = date('Y-m-d H:i:s');
    
            $authUser = $this->Session->read('Auth.User');
            $storeId = $authUser['location_id'] ?? 0;
            $store_name = $authUser['location_name'] ?? 0;
            
            // $loc = $this->Location->find('first', [
            //     'conditions' => ['Location.id' => $storeId],
            //     'fields' => ['Location.name'],
            //     'recursive' => -1
            // ]);
            
            // $store_name = isset($loc['Location']['name']) ? $loc['Location']['name'] : '';
            
            do {
                // Generate a numeric-only ID: remove non-digits and trim to 12 digits
                $pos_audit_id = preg_replace('/\D/', '', substr(sha1(uniqid() . rand()), 0, 32));
                $pos_audit_id = substr($pos_audit_id, 0, 12); // Adjust digit length as needed
                if ($pos_audit_id[0] === '0') {
                    $pos_audit_id[0] = strval(rand(1, 9)); // replace first digit with 1–9
                }
                
                // Check for uniqueness in both pos_auditstock and temp_audit_stock tables
                $existsMain = $this->Audit_stock->find('count', [
                    'conditions' => ['Audit_stock.pos_audit_id' => $pos_audit_id],
                    'recursive' => -1
                ]);
            
                $existsTemp = $this->Temp_audit_stock->find('count', [
                    'conditions' => ['Temp_audit_stock.pos_audit_id' => $pos_audit_id],
                    'recursive' => -1
                ]);
            
            } while ($existsMain > 0 || $existsTemp > 0);
            
            $selectAll = ($submitAll === 'yes') ? 1 : 0;
    
            $header = [
                'pos_audit_id' => $pos_audit_id,
                'store_id' => $storeId,
                'store_name' => $store_name,
                'remarks' => $remarks,
                'status' => 1,
                'item_type' => 'semifinished',
                'type' => 'DC',
                'select_all' => $selectAll,
                'updateon' => $createdTime
            ];
    
            $quantities = $data['quantity'] ?? [];
            // print_r($data['quantity']);exit;
            
                
            $items = [];
            
            if (isset($data['prepare_submit'])) {
                foreach ($quantities as $skuId => $qty) {
                    $qty = floatval($qty);
                    if ($qty <= 0) continue;
                
                    // Get last audit info
                    $lastAudit = $this->Audit_stock_items->find('first', [
                        'conditions' => ['sku_id' => $skuId,'item_type' => 'Semifinished','type' => 'DC', 'status' => 1],
                        'order' => ['id DESC'],
                        'fields' => ['physicalstock', 'auditto'],
                        'recursive' => -1
                    ]);
                
                    $openingstock = 0;
                    $auditfrom = '2025-01-01 00:00:01';
                
                    if (!empty($lastAudit)) {
                        $openingstock = floatval($lastAudit['Audit_stock_items']['physicalstock']);
                        $auditfrom = $lastAudit['Audit_stock_items']['auditto'];
                    }
                
                    $variance = $qty - $openingstock;
                    $auditto = $auditDate . ' ' . $auditTime . ':00';
                
                    $skuName = $data['sku_name'][$skuId] ?? '';
                    $unitId = (int)($data['unit_id'][$skuId] ?? 0);
                    $unitName = $data['unit_name'][$skuId] ?? '';
                    $sku_price=$data['price'][$skuId] ?? 0;
                    
                    $auditItem = [
                        'sku_id' => $skuId,
                        'pos_audit_id' => $pos_audit_id,
                        'sku_name' => $skuName,
                        'item_type' => 'Semifinished',
                        'type' => 'DC',
                        'sku_unit' => $unitId,
                        'sku_unit_name' => $unitName,
                        'sku_price'=>$sku_price,
                        'openingstock' => $openingstock,
                        'closingstock' => 0,
                        'physicalstock' => $qty,
                        'variance' => $variance,
                        'auditfrom' => $auditfrom,
                        'auditto' => $auditto,
                        'remarks' => $remarks,
                        'status' => 1,
                        'created' => $createdTime,
                        'modified' => $createdTime,
                        'sync'=>0,
                        'local_sync'=>0
                    ];
                
                    $this->Audit_stock_items->create();
                    $this->Audit_stock_items->save($auditItem);
                
                    
                    $skuquantityForLedger = $qty;
                
                    $ledgerEntries = $this->Stock_ledger->find('all', [
                        'conditions' => [
                            'store_id' => $storeId,
                            'sku_id' => $skuId,
                            'item_type'=>'Semifinished',
                            'type' => 'DC',
                            'record_type !=' => 'audit_stock',
                            'created >' => $auditto
                        ],
                        'order' => ['created ASC'],
                        'recursive' => -1
                    ]);
                
                    if (!empty($ledgerEntries)) {
                        foreach ($ledgerEntries as $entry) {
                            $ledger = $entry['Stock_ledger'];
                            $prevQuantity = floatval($ledger['quantity']);
                            $quantityType = $ledger['quantity_type'];
                
                            $newBalance = ($quantityType === 'credit')
                                ? $skuquantityForLedger + $prevQuantity
                                : $skuquantityForLedger - $prevQuantity;
                
                            $this->Stock_ledger->id = $ledger['id'];
                            $this->Stock_ledger->save([
                                'variance' => $variance,
                                'actual_balance' => $newBalance,
                                'variance_type' => 'back_audit',
                                'variance_id' => $pos_audit_id,
                                'modified' => $createdTime,
                                'sync'=>0,
                                'local_sync'=>0
                            ]);
                
                            $skuquantityForLedger = $newBalance;
                        }
                    } else {
                        // Insert fresh ledger row
                        $this->Stock_ledger->create();
                        $this->Stock_ledger->save([
                            'store_id' => $storeId,
                            'sku_id' => $skuId,
                            'sku_name' => $skuName,
                            'sku_price'=>$sku_price,
                            'unit_id' => $unitId,
                            'unit_name' => $unitName,
                            'record_id' => $pos_audit_id,
                            'record_type' => 'audit_stock',
                            'quantity' => 0,
                            'balance_stock' => 0,
                            'variance' => $variance,
                            'actual_balance' => $qty,
                            'variance_type' => 'audit',
                            'variance_id' => $pos_audit_id,
                            'item_type' => 'Semifinished',
                            'type' => 'DC',
                            'quantity_type' => 'audit',
                            'created' => $auditto,
                            'modified' => $createdTime,
                            'sync'=>0,
                            'local_sync'=>0
                        ]);
                    }
                }
                
                // Save audit_stock header
                if ($this->Audit_stock->save($header)) {
                    $this->Flash->success(__('Audit submitted successfully.'));
                    return $this->redirect(['action' => 'semi_auditstock']);
                } else {
                    $this->Flash->error(__('Failed to submit audit.'));
                }
            }
        }
    }
    
    public function semi_view_audit()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Audit_stock->query("SELECT * FROM pos_auditstock where pos_audit_id=$id");
        $this->set(compact('indents'));
        
        $items = $this->Audit_stock_items->query("SELECT * FROM pos_auditstock_items where pos_audit_id=$id and status=1");
        
        $this->set(compact('items'));
        
        
    }
    
    public function kds_users() 
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend; 
        
        $params = [
            'start' => "$startDatetime",
            'end'   => "$endDatetime"
        ];
        
        $locationCondition = "";
        if ($userRole !== 'admin') {
            $locationCondition = " AND ku.location_id = :location_id";
            $params['location_id'] = $userLocationId; // assign normally, not using IN here
        }
        
        $sql = "
            SELECT ku.*,
                   GROUP_CONCAT(kusm.station_name) AS stations
            FROM kds_users ku
            LEFT JOIN kds_users_station_mapping kusm ON kusm.kds_id = ku.id AND kusm.status = 1
            WHERE 1=1
                  $locationCondition
                  AND ku.created BETWEEN :start AND :end
            GROUP BY ku.id ORDER BY ku.id DESC
        ";
        
        $users = $this->Kds_user->query($sql, $params);


        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function create_kds_users()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $conditions = ['status' => 1];
        if ($userRole !== 'admin') {
            $conditions['id IN'] = (array)$userLocationId; // works for single or multiple
        }
        
        $locations = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        $this->set(compact('locations'));
        
        $stations = $this->Pos_printer->find('all', array('conditions' => array('status' => 1)));
        $this->set(compact('stations'));
        
        
        if ($this->request->is(array('post', 'put'))) {
            
            $username = $this->data['User']['username'];
            $userdetail=$this->Kds_user->find('first',array('conditions'=>array('username'=>$username)));
            if($userdetail){
                $this->Flash->error(__('Username already exist'));
                return $this->redirect(array('action' => 'create_kds_users'));
            }
            
            $password = $this->data['User']['password'];
            $password = AuthComponent::password($password);
            $location = $this->data['User']['location'];
            $role = $this->data['User']['role'];
            $locationdetail=$this->Location->find('first',array('conditions'=>array('Location.id'=>$location)));
            $locationname=$locationdetail['Location']['name'];
            $data['Kds_user']=array(
                'username'=>$username,
                'password'=>$password,
                'role'=>$role,
                'location_id'=>$location,
                'location_name'=>$locationname,
                'sync'=>0,
                'local_sync'=>0
            );
            
            if($this->Kds_user->save($data['Kds_user']))
            {
                $kds_id = $this->Kds_user->id;
                
                foreach ($_POST['station_ids'] as $station_id) {
                    $stationdetail = $this->Pos_printer->find('first', [
                        'conditions' => ['Pos_printer.id' => $station_id],
                        'recursive' => -1
                    ]);
                
                    if (!$stationdetail) {
                        continue;
                    }
                
                    $data['Kds_users_station_mapping'] = [
                        'kds_id' => $kds_id,
                        'kds_username' => $username,
                        'station_id' => $station_id,
                        'station_name' => $stationdetail['Pos_printer']['name'],
                        'station_store_id' => $location,
                        'station_store_name' => $locationname,
                        'sync'=>0,
                        'local_sync'=>0
                    ];
                
                    if (!$this->Kds_users_station_mapping->saveAll($data['Kds_users_station_mapping'])) {
                        $this->Flash->error(__('KDS User Station Mapping could not be saved. Please, try again.'));
                    }
                }

                $this->Flash->success(__('Kds User has been saved.'));
                return $this->redirect(array('action' => 'kds_users'));
            } else {
                $this->Flash->error(__('kds User could not be saved. Please, try again.'));
            }
        }
    }
    
    public function kds_users_change_status() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Kds_user->id = $Id;
            $newStatus = $this->Kds_user->field('status') == 1 ? 0 : 1;
            
            if ($this->Kds_user->save(['status' => $newStatus,'sync' => 0,'local_sync' => 0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function get_stations_by_location()
    {
        $this->autoRender = false;
        $locationId = $this->request->query('location_id');
    
        if (!$locationId) {
            echo json_encode(['status' => false, 'message' => 'Location ID missing']);
            return;
        }
    
        $stations = $this->Pos_printer->find('all', [
            'conditions' => [
                'Pos_printer.status' => 1
            ],
            'fields' => ['id', 'name']
        ]);
    
        $data = [];
        foreach ($stations as $station) {
            $data[] = [
                'id' => $station['Pos_printer']['id'],
                'name' => $station['Pos_printer']['name']
            ];
        }
    
        echo json_encode(['status' => true, 'stations' => $data]);
    }

    public function edit_kds_users()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = 'users';
        $stations = $this->Pos_printer->find('all', array('conditions' => array('status' => 1)));
        $this->set(compact('stations'));
    
        /* ======================
           SAVE POST DATA
        ====================== */
        if ($this->request->is('post')) {
    
            $data = $this->request->data['Kds_user'];
    
            $id       = $data['id'] ?? null;
            $username = trim($data['username'] ?? '');
            $password = trim($data['password'] ?? '');
            $location = (int)($data['location'] ?? 0);
            $role     = $data['role'] ?? '';
            $stations = $this->request->data['station_ids'] ?? [];
    
            if (!$id || $username === '') {
                $this->Flash->error(__('Invalid data.'));
                return $this->redirect(['action' => 'kds_users']);
            }
    
            /* Location details */
            $locationDetail = $this->Location->find('first', [
                'conditions' => ['Location.id' => $location],
                'recursive' => -1
            ]);
    
            $storeName = $locationDetail['Location']['name'] ?? '';
    
            /* Update KDS User */
            $updateData = [
                'username'      => $username,
                'role'          => $role,
                'location_id'      => $location,
                'location_name'    => $storeName,
                'sync'          => 0,
                'local_sync'    => 0
            ];
    
            $this->Kds_user->id = $id;
            $this->Kds_user->save($updateData);
    
            /* Update password only if entered */
            if (!empty($password)) {
                $this->Kds_user->saveField(
                    'password',
                    AuthComponent::password($password)
                );
            }
    
            /* ======================
               SOFT DELETE OLD STATIONS
            ====================== */
            $this->Kds_users_station_mapping->updateAll(
                [
                    'Kds_users_station_mapping.status' => 0,
                    'Kds_users_station_mapping.sync' => 0,
                    'Kds_users_station_mapping.local_sync' => 0
                ],
                ['Kds_users_station_mapping.kds_id' => $id]
            );
    
            /* ======================
               SAVE NEW STATIONS
            ====================== */
            if (!empty($stations)) {
                foreach ($stations as $stationId) {
    
                    $station = $this->Pos_printer->find('first', [
                        'conditions' => ['id' => $stationId],
                        'recursive' => -1
                    ]);
    
                    if ($station) {
                        $this->Kds_users_station_mapping->create();
                        $this->Kds_users_station_mapping->save([
                            'kds_id'                 => $id,
                            'kds_username'           => $username,
                            'station_id'             => $stationId,
                            'station_name'           => $station['Pos_printer']['name'],
                            'station_store_id'       => $location,
                            'station_store_name'     => $storeName,
                            'status'                 => 1,
                            'sync'=>0,
                            'local_sync'=>0
                        ]);
                    }
                }
            }
    
            $this->Flash->success(__('KDS User updated successfully.'));
            return $this->redirect(['action' => 'kds_users']);
        }
    
        /* ======================
           LOAD EDIT PAGE DATA
        ====================== */
    
        $id = $this->request->query('id');
        if (!$id) {
            $this->Flash->error(__('Invalid user ID.'));
            return $this->redirect(['action' => 'kds_users']);
        }
    
        $userDetail = $this->Kds_user->find('first', [
            'conditions' => ['id' => $id],
            'recursive' => -1
        ]);
        $this->set(compact('userDetail'));
    
        $locations = $this->Location->find('all', [
            'conditions' => ['status' => 1],
            'recursive' => -1
        ]);
        $this->set(compact('locations'));
    
        $stationMappings = $this->Kds_users_station_mapping->find('list', [
            'fields' => ['station_id'],
            'conditions' => [
                'kds_id' => $id,
                'status' => 1
            ],
            'recursive' => -1
        ]);
        $this->set('selectedStations', array_values($stationMappings));
    }

     public function unit_mapping() 
	{
	    if(!$this->Session->check('Auth.User.id')){
			$this->redirect(array('controller'=>'dashboard','action' => 'login'));		
		}
        
	    $this->layout = "users";
		
		$startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
			$daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
		
		$users = $this->Catalog_unit_mapping->query("SELECT * FROM catalog_unit_mapping where created between '$startDatetime' and  '$endDatetime' ORDER BY id desc");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
		$this->set(compact('users'));

	}
	
    public function create_unit_mapping()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
    
        $units = $this->Catalog_unit->find('all', ['conditions' => ['status' => 1]]);
        $this->set(compact('units'));
    
        
        if ($this->request->is(array('post', 'put'))) {
            
            $unit = $this->data['User']['unit'];
            if($unit==''){
                $this->Flash->error(__('The Unit could not be Blank'));
                return $this->redirect(array('action' => 'create_unit_mapping'));
            }
            $unit_id = (int)$unit;
            $unitData = $this->Catalog_unit->findById($unit_id);
            $unit_name = $unitData['Catalog_unit']['name'] ?? '';
            
            $con_unit = $this->data['User']['con_unit'];
            if($con_unit==''){
                $this->Flash->error(__('The Unit could not be Blank'));
                return $this->redirect(array('action' => 'create_unit_mapping'));
            }
            $con_unit_id = (int)$con_unit;
            $con_unitData = $this->Catalog_unit->findById($con_unit_id);
            $con_unit_name = $con_unitData['Catalog_unit']['name'] ?? '';
            
            $factor = $this->data['User']['factor'];
            
            $data['Catalog_unit_mapping']=array(
                'unit_id'=>$unit,
                'unit_name'=>$unit_name,
                'mapped_unit_id'=>$con_unit,
                'mapped_unit_name'=>$con_unit_name,
                'conversion_factor'=>$factor,
                'sync'=>0,
                'local_sync'=>0
            );
            
            if($this->Catalog_unit_mapping->saveAll($data['Catalog_unit_mapping']))
            {
				$recalculated=$this->recalculate_food_costs();
                $this->Flash->success(__('Unit has been mapped.'));
                return $this->redirect(array('action' => 'unit_mapping'));
            } else {
                $this->Flash->error(__('Unit could not be mapped. Please, try again.'));
            }
        }
    }
    
    public function edit_unit_mapping() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        $id = $this->request->query('id'); // safer than $_REQUEST
    
        // Load units for dropdowns
        $units = $this->Catalog_unit->find('all', ['conditions' => ['status' => 1]]);
        $this->set(compact('units'));
    
        // Load existing mapping record
        $mapping = $this->Catalog_unit_mapping->findById($id);
        if (!$mapping) {
            $this->Flash->error('Mapping not found');
            return $this->redirect(['action' => 'unit_mapping']);
        }
        $this->set('products', [$mapping]);  // your view uses $products[0]
    
        if ($this->request->is(['post', 'put'])) {
            // Update mapping record
            $unit_id = $this->data['User']['unit'];
            $unitData = $this->Catalog_unit->findById($unit_id);
            $unit_name = $unitData['Catalog_unit']['name'] ?? '';
            
            $con_unit_id = $this->data['User']['con_unit'];
            $con_unitData = $this->Catalog_unit->findById($con_unit_id);
            $con_unit_name = $con_unitData['Catalog_unit']['name'] ?? '';
            
            $this->Catalog_unit_mapping->id = $id;
            $data = [ 
                'unit_id' => $this->request->data['User']['unit'],
                'unit_name' => $unit_name,
                'mapped_unit_id' => $this->request->data['User']['con_unit'],
                'mapped_unit_name' => $con_unit_name,
                'conversion_factor' => $this->request->data['User']['factor'],
                'sync' =>0,
                'local_sync' =>0
            ];
            
            if ($this->Catalog_unit_mapping->save($data)) {
				$recalculated=$this->recalculate_food_costs();
                $this->Flash->success('Unit mapping has been updated.');
                return $this->redirect(['action' => 'unit_mapping']);
            } else {
                $this->Flash->error('Unable to update unit mapping.');
            }
        } else {
            // Populate form with existing data
            $this->request->data['User'] = [
                'unit' => $mapping['Catalog_unit_mapping']['unit_id'],
                'con_unit' => $mapping['Catalog_unit_mapping']['mapped_unit_id'],
                'factor' => $mapping['Catalog_unit_mapping']['factor'],
            ];
        }
    }

    
    
    public function unit_mapping_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            $this->Catalog_unit_mapping->id = $Id;
            $newStatus = $this->Catalog_unit_mapping->field('status') == 1 ? 0 : 1;
            
            if ($this->Catalog_unit_mapping->save(['status' => $newStatus,'sync' => 0,'local_sync'=>0])) {
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function get_mapped_units() {
        $this->autoRender = false;  // no view
    
        $unit_id = $this->request->query('unit_id');
    
        if (!$unit_id) {
            echo json_encode([]);
            return;
        }
    
        // Fetch mapped units for the selected unit_id
        $mappedUnits = $this->Catalog_unit_mapping->find('all', [
            'conditions' => ['unit_id' => $unit_id, 'status' => 1],
            'fields' => ['mapped_unit_id', 'mapped_unit_name'],
            'recursive' => -1,
        ]);
    
        // Format for JSON
        $result = [];
        foreach ($mappedUnits as $mu) {
            $result[] = [
                'mapped_unit_id' => $mu['Catalog_unit_mapping']['mapped_unit_id'],
                'mapped_unit_name' => $mu['Catalog_unit_mapping']['mapped_unit_name'],
            ];
        }
    
        echo json_encode($result);
    }
    
    public function get_conversion_factor() {
        $this->autoRender = false;
    
        $unit_id = $this->request->query('unit_id');
        $mapped_unit_id = $this->request->query('mapped_unit_id');
    
        if (!$unit_id || !$mapped_unit_id) {
            echo json_encode([]);
            return;
        }
    
        $mapping = $this->Catalog_unit_mapping->find('first', [
            'conditions' => [
                'unit_id' => $unit_id,
                'mapped_unit_id' => $mapped_unit_id,
                'status' => 1
            ],
            'fields' => ['conversion_factor'],
            'recursive' => -1,
        ]);
    
        if ($mapping) {
            echo json_encode(['factor' => $mapping['Catalog_unit_mapping']['conversion_factor']]);
        } else {
            echo json_encode(['factor' => null]);
        }
    }
    
    public function kds_reports()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
            
        $cashier_id= $this->request->data['Search']['cashier'];
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        if ($userRole !== 'admin') {
        
            if(!$cashier_id){
                $cashier_id = $authUser['location_ids'] ?? 0;
            }
            $users = $this->Kds_track->query("SELECT k.*, (SELECT name FROM pos_printers WHERE id = k.kds_station_id) AS station_name 
                FROM kds_tracks k
                 WHERE created BETWEEN '$startDatetime' and  '$endDatetime' and location_id=$cashier_id
                ORDER BY k.id DESC;
            ");
        }else{
            if(!$cashier_id){
                $users = $this->Kds_track->query("SELECT k.*, (SELECT name FROM pos_printers WHERE id = k.kds_station_id) AS station_name 
                    FROM kds_tracks k
                     WHERE created BETWEEN '$startDatetime' and  '$endDatetime'
                    ORDER BY k.id DESC;
                "); 
            }else{
                $users = $this->Kds_track->query("SELECT k.*, (SELECT name FROM pos_printers WHERE id = k.kds_station_id) AS station_name 
                    FROM kds_tracks k
                     WHERE created BETWEEN '$startDatetime' and  '$endDatetime' and location_id=$cashier_id
                    ORDER BY k.id DESC;
                ");
            }
        }
    
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));
        
        $userLocationId = $authUser['location_ids'] ?? 0;
        
        $locationCondition = ['status' => 1]; // always filter by active locations

        if ($userRole !== 'admin') {
            // Ensure it's always an array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP will auto-convert to IN()
        }
        
        $cashier_users = $this->Location->find('all', [
            'conditions' => $locationCondition
        ]);

        $this->set(compact('cashier_users'));
       // print_r($locationCondition);exit;

    }
    
    public function kds_reportexport() {
        $date_range= $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate= date('Y-m-d', strtotime($start_date));
        $enddate= date('Y-m-d', strtotime($end_date));
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $cashier_id = isset($_GET['cashier']) ? $_GET['cashier'] : '';
        // Get transactions
        $conditions = array();
        $conditions[] = "created BETWEEN '$startDatetime' and  '$endDatetime'";
        if ($cashier_id) {
            $conditions[] = "location_id=" . (int)$cashier_id;
            $cashiernames = $this->Location->find('first', array('conditions' => array('Location.id' => $cashier_id)));
            $cashiername  = !empty($cashiernames['Location']['name']) ? $cashiernames['Location']['name'] : 'Unknown Cashier';
        } else {
            $cashiername = 'All Stores';
        }
        $where = implode(' AND ', $conditions);
        
        $transactions = $this->Kds_track->query("
            SELECT k.*, (SELECT name FROM pos_printers WHERE id = k.kds_station_id) AS station_name 
            FROM kds_tracks k
            WHERE $where
            ORDER BY k.id DESC
        ");
    
        // Prepare data for Excel
        $datas = array();
        foreach ($transactions as $user) {
            $statusLabel = '';
            switch ($user['k']['status']) {
                case 0: $statusLabel = 'Unfire'; break;
                case 1: $statusLabel = 'Fire'; break;
                case 2: $statusLabel = 'Hold'; break;
                case 3: $statusLabel = 'Start'; break;
                case 4: $statusLabel = 'Bump'; break;
                case 5: $statusLabel = 'Flag'; break;
                case 6: $statusLabel = 'Send to Table'; break;
                case 7: $statusLabel = 'Recall'; break;
                default: $statusLabel = 'Unknown'; break;
            }
            $datas[] = array(
                'Reference ID'   => $user['k']['order_reference_id'],
                'Group ID'       => $user['k']['kds_group_id'],
                'KDS Station'    => !empty($user[0]['station_name']) ? $user[0]['station_name'] : '',
                'Product Name'   => $user['k']['product_name'],
                'Role'           => $user['k']['role'],
                'Location Name'  => $user['k']['location_name'],
                'Status'         => $statusLabel,
                'Created'        => $user['k']['created'],
            );
        }
    
        // Load PHPExcel
        App::import('Vendor', 'PHPExcel', array('file' => 'PHPExcel/PHPExcel.php'));
        App::import('Vendor', 'PHPExcel_IOFactory', array('file' => 'PHPExcel/PHPExcel/IOFactory.php'));
        error_reporting(0);
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("KDS Transaction Report")
            ->setSubject("Transaction Report")
            ->setDescription("Exported KDS transaction data.")
            ->setCategory("Export Data");
    
        // Set headers
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', "TRANSACTION REPORT FROM $startdate TO $enddate ($cashiername)");
        $objPHPExcel->getActiveSheet()->mergeCells('A1:H1');
        $objPHPExcel->getActiveSheet()->getStyle("A1:H1")->getFont()->setBold(true);
    
        // Column headings for Excel
        $headers = array('SR. NO.', 'Reference ID', 'Group ID', 'KDS Station', 'Product Name', 'Role', 'Location Name', 'Status', 'Created');
        foreach ($headers as $col => $heading) {
            $colLetter = PHPExcel_Cell::stringFromColumnIndex($col);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue($colLetter . '2', $heading);
            $objPHPExcel->getActiveSheet()->getStyle($colLetter . '2')->getFont()->setBold(true);
        }
    
        // Data rows
        $rowNum = 3;
        foreach ($datas as $idx => $dat) {
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A' . $rowNum, ($idx + 1));
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B' . $rowNum, $dat['Reference ID']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C' . $rowNum, $dat['Group ID']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D' . $rowNum, $dat['KDS Station']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E' . $rowNum, $dat['Product Name']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F' . $rowNum, $dat['Role']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G' . $rowNum, $dat['Location Name']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H' . $rowNum, $dat['Status']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I' . $rowNum, $dat['Created']);
            $rowNum++;
        }
    
        $objPHPExcel->getActiveSheet()->setTitle('Export Data');
        $objPHPExcel->setActiveSheetIndex(0);
    
        // Output to browser
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="kds_REPORT.xls"');
        header('Cache-Control: max-age=0');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Past date
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    
    
    public function view_kds_report()
    {
        // Session check (as before)
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));     
        }
        $this->layout = "users";
        
        $id = $_REQUEST['id'];
    
        // Fetch with station name in result
        $flatProducts = $this->Kds_track->query(
            "SELECT *, (SELECT name FROM pos_printers WHERE id = kds_tracks.kds_station_id) AS station_name 
            FROM kds_tracks 
            WHERE order_reference_id = '$id'"
        );
        // Group by station_name and product_name
        $stations = [];
        foreach ($flatProducts as $row) {
            // Get station name
            $stationName = isset($row[0]['station_name']) ? $row[0]['station_name'] : $row['kds_tracks']['station_name'];
            // Get product data structure (may need to adjust based on your query result)
            $data = isset($row['kds_tracks']) ? $row['kds_tracks'] : (isset($row[0]) ? $row[0] : $row);
            // Get product name
            $productName = $data['product_name'];
            // Group by [station][product][]
            $stations[$stationName][$productName][] = $row;
        }
    
        $this->set(compact('stations'));
    }

    
    //bracnhes code
    //branches
    public function store_category() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole == 'subadmin'){
            $id = $authUser['id'];                      
            $userLocationId = $this->User_location->find('list', [
                'conditions' => ['status' => 1, 'user_id' => $id],
                'fields' => ['location_id']
            ]);
        }
        
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        
        if ($userRole !== 'admin') {
            // Always cast to array so CakePHP handles IN() automatically
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $conditions['id IN'] = $userLocationIds;
        }
        $cashier_users = $this->Location->find('all', [
            'conditions' => $conditions
        ]);
        $this->set(compact('cashier_users'));
     
        $location_id = null;
        if (isset($this->request->data['Search'])) {
            $location_id= $this->request->data['Search']['cashier'];
        }
        if (isset($this->request->query['location_id'])) {
            $location_id = $this->request->query['location_id'];
            $this->request->data['Search']['cashier'] = $location_id;
        }

        

        $users = $this->Catalog_category_branches->find('all', array(
            'conditions' => array('location_id' =>$location_id, 'status' => 1),
            'order' => array(
                'id' => 'DESC' 
            )
        ));
        
        // $dbo = $this->Catalog_category_branches->getDataSource();
        // $logs = $dbo->getLog();
        // $lastQuery = end($logs['log']);
        // debug($lastQuery);die;
        
        $this->set(compact('users'));

    }
    
    //Manage store categories
    public function manage_store_category() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_id'] ?? 0;
        
        $this->layout = "users";
        
        $locationCondition = '';
        if ($userRole !== 'admin' || $userRole !== 'subadmin') {
            $locationCondition = "id = " . (int)$userLocationId;
        }

        $locationId = isset($this->request->query['loc_id']) ? $this->request->query['loc_id'] : null;
        $existingCategories = array();
        
        if ($locationId) {

            $locationname = $this->Location->field('name', array('id' => $locationId));
            
            $this->set(compact('locationname'));
            $this->set(compact('locationId'));

            $existingCategories = $this->Catalog_category_branches->find('list', array(
                'fields' => ['category_id', 'category_id'],
                'conditions' => array(
                    'location_id' => $locationId,
                    'status' => 1
                )
            ));
            if(!empty($existingCategories)){
                $allCategories = $this->Catalog_category->find('all', [
                    'fields' => ['id', 'name'],
                    'conditions' => ['status' => 1, 'NOT' => ['id' => $existingCategories]]
                ]);
            }
            else{
                $allCategories = $this->Catalog_category->find('all', [
                    'fields' => ['id', 'name'],
                    'conditions' => ['status' => 1]
                ]);
            }
            

            $this->set(compact('allCategories'));
        }
        

    }

    public function assign_categories_to_store(){
        $this->autoRender = false; 
    
        if ($this->request->is('post')) {
            $category_ids = $this->request->data['category_ids'];
            $store_id = $this->request->data['store_id'];
            $storename = $this->request->data['store_name'];

            $saveData = [];
            foreach ($category_ids as $catId) {
                $category_name = $this->Catalog_category->field('name', ['id' => $catId]);
                $saveData[] = [
                    'location_id' => $store_id,       
                    'category_id' => (int)$catId,   
                    'category_name' => $category_name,   
                    'location_name' => $storename,
                    'sync'=>0,
                    'local_sync'=>0
                ];
            }

            if ($this->Catalog_category_branches->saveAll($saveData)) {
                $this->Flash->success(__('Categories saved successfully.'));
                $this->autoRender = false;
                $this->response->type('json');
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function change_store_category_status() {
        $this->autoRender = false; 
    
        if ($this->request->is('post')) {
            $categoryId = $this->request->data['_id'];
            $location_id = $this->request->data['loc_row_id'];
              $category =  $this->Catalog_category_branches->updateAll(
                    ['status' => 0,'sync' => 0,'local_sync' => 0],          // fields to update
                    ['category_id' => $categoryId, 'location_id' => $location_id]  // condition
                );
                if ($category) {
                    echo json_encode(['status' => true]);
                } else {
                    echo json_encode(['status' => false]);
                }
           
        }
    }

    public function store_products() {
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole == 'subadmin'){
            $id = $authUser['id'];                      
            $userLocationId = $this->User_location->find('list', [
                'conditions' => ['status' => 1, 'user_id' => $id],
                'fields' => ['location_id']
            ]);
        }
        
        $this->layout = "users";
        $this->loadModel('Catalog_product_branches');

        $locationCondition = [
            'status' => 1,
            'type'   => 'Outlet'
        ]; // always filter by active outlets
        
        if ($userRole !== 'admin') {
            // Ensure it’s always an array
            $userLocationIds = is_array($userLocationId) ? $userLocationId : [$userLocationId];
            $locationCondition['id'] = $userLocationIds; // CakePHP will convert to IN()
        }
        
        $cashier_users = $this->Location->find('all', [
            'conditions' => $locationCondition
        ]);

        $this->set(compact('cashier_users'));
        $location_id = null;
        if (isset($this->request->data['Search']['cashier'])) {
            $location_id = $this->request->data['Search']['cashier'];
        }
        if (isset($this->request->query['location_id'])) {
            $location_id = $this->request->query['location_id'];
            $this->request->data['Search']['cashier'] = $location_id;
        }

        $assignedCategories = [];
        
        $assignedCategories = $this->Catalog_product_branches->find('all', [
            'conditions' => ['location_id' => $location_id, 'status' => 1],
            'order' => ['id' => 'DESC']
        ]);
        $this->set(compact('assignedCategories'));
    }

    public function manage_store_products() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));
        }

        $authUser = $this->Session->read('Auth.User');
        $this->layout = "users";
        
        $this->loadModel('Catalog_product_branches');

        $locationId = isset($this->request->query['loc_id']) ? $this->request->query['loc_id'] : null;
        if ($locationId) {
            $locationname = $this->Location->field('name', array('id' => $locationId));
            $this->set(compact('locationId'));
            $this->set(compact('locationname'));
        }

        $existingProducts = $this->Catalog_product_branches->find('list', array(
                'fields' => ['product_id', 'product_id'],
                'conditions' => array(
                    'location_id' => $locationId,
                    'status' => 1
                )
            ));
        
        if(!empty($existingProducts)){
            $products = $this->Catalog_product->find('all', [
                'fields' => ['id', 'name', 'cat_id', 'cat_name', 'subcat_id', 'subcat_name','unit', 'unit_name','price'],
                'conditions' => ['status' => 1, 'NOT' => ['id' => $existingProducts]]
            ]);
        } else {
            $products = $this->Catalog_product->find('all', [
                'fields' => ['id', 'name', 'cat_id', 'cat_name', 'subcat_id', 'subcat_name','unit', 'unit_name','price'],
                'conditions' => ['status' => 1]
            ]);
        }
       
        $this->set(compact('products'));


    }

    public function assign_products_to_store(){
        $this->autoRender = false; 
        
        if ($this->request->is('post')) {

            
        $this->loadModel('Catalog_product_branches');

            $product_ids = $this->request->data['product_ids'];
            $store_id = $this->request->data['store_id'];
            $storename = $this->request->data['store_name'];
            $prices = $this->request->data['prices'];

            $saveData = [];
            foreach ($product_ids as $prodId) {
                
                $products = $this->Catalog_product->find('all', [
                    'fields' => ['id', 'name', 'cat_id', 'cat_name', 'subcat_id', 'subcat_name','unit', 'unit_name','price'],
                    'conditions' => ['status' => 1, 'id' => $prodId]
                ]);
                if (!empty($products)) {

                    $product = $products[0]['Catalog_product'];
                    $price = isset($prices[$prodId]) ? floatval($prices[$prodId]) : $product['price'];

                    $saveData[] = [
                        'location_id' => $store_id,       
                        'location_name' => $storename,
                        'product_id' => (int)$prodId,   
                        'product_name' => $product['name'],   
                        'cat_id' => $product['cat_id'],
                        'cat_name' => $product['cat_name'],
                        'subcat_id' => $product['subcat_id'],
                        'subcat_name' => $product['subcat_name'],
                        'unit' => $product['unit'],
                        'unit_name' => $product['unit_name'],
                        'price' => $price,
                        'sync'=>0,
                        'local_sync'=>0
                    ];
                }
            }

            if ($this->Catalog_product_branches->saveAll($saveData)) {
                $this->Flash->success(__('Products assigned successfully.'));
                $this->autoRender = false;
                $this->response->type('json');
                echo json_encode(['status' => true]);
            } else {
                echo json_encode(['status' => false]);
            }
        }
    }
    
    public function change_store_product_status() {
        $this->autoRender = false; 
        
        $this->loadModel('Catalog_product_branches');
        if ($this->request->is('post')) {
            $product_id = $this->request->data['product_id'];
            $location_id = $this->request->data['loc_row_id'];
              $category =  $this->Catalog_product_branches->updateAll(
                    ['status' => 0,'sync' => 0,'local_sync' => 0],          // fields to update
                    ['product_id' => $product_id, 'location_id' => $location_id]  // condition
                );
                if ($category) {
                    echo json_encode(['status' => true]);
                } else {
                    echo json_encode(['status' => false]);
                }
           
        }
    }

    public function copy_store_categories() {
        $this->autoRender = false; 
        
        if ($this->request->is('post')) {
             $current_store_id = $this->request->data['store_id'];
             $copy_from_store = $this->request->data['copy_from_store'];

            $existingCategories = $this->Catalog_category_branches->find('list', array(
                'fields' => ['category_id', 'category_id'],
                'conditions' => array(
                    'location_id' => $current_store_id,
                    'status' => 1
                )
            ));
            if(!empty($existingCategories)){
                $data = $this->Catalog_category_branches->find('all', array(
                    'conditions' => array('location_id' =>$copy_from_store, 'status' => 1, 'NOT' => ['category_id' => $existingCategories]),
                    'order' => array(
                        'id' => 'DESC')
                ));
                
            }   
            else{
                $data = $this->Catalog_category_branches->find('all', array(
                    'conditions' => array('location_id' =>$copy_from_store, 'status' => 1),
                    'order' => array(
                        'id' => 'DESC')
                ));
            }
            
            $locationname = $this->Location->field('name', array('id' => $current_store_id));

            $saveData = [];
            foreach ($data as $item) {
                $saveData[] = [
                    'location_id' => $current_store_id,       
                    'category_id' => $item['Catalog_category_branches']['category_id'],   
                    'category_name' => $item['Catalog_category_branches']['category_name'],   
                    'location_name' => $locationname,
                    'sync'=>0,
                    'local_sync'=>0
                ];  
            }
            if (!empty($saveData)) {

                if ($this->Catalog_category_branches->saveAll($saveData)) {
                    $this->Flash->success(__('Categories copied successfully.'));
                    $this->redirect(array('action' => 'store_category','?'=>array('location_id'=>$current_store_id)));
                    $this->autoRender = false;
                } else {
                    $this->Flash->error(__('Categories could not be copied. Please, try again.'));
                    $this->redirect(array('action' => 'store_category','?'=>array('location_id'=>$current_store_id)));
                }
                        
            } else {
                $this->Flash->success(__('No categories to copy from the selected store.'));
                $this->redirect(array('action' => 'store_category','?'=>array('location_id'=>$current_store_id)));
            }
        }
    }

    public function copy_store_products() {
        $this->autoRender = false;
        $this->loadModel('Catalog_product_branches');

        if ($this->request->is('post')) {
             $current_store_id = $this->request->data['store_id'];
             $copy_from_store = $this->request->data['copy_from_store'];

            $existingProducts = $this->Catalog_product_branches->find('list', array(
                'fields' => ['product_id', 'product_id'],
                'conditions' => array(
                    'location_id' => $current_store_id,
                    'status' => 1
                )
            ));
                
            if(!empty($existingProducts)){
                $data = $this->Catalog_product_branches->find('all', array(
                    'conditions' => array('location_id' =>$copy_from_store, 'status' => 1, 'NOT' => ['product_id' => $existingProducts]),
                    'order' => array(
                        'id' => 'DESC' 
                    )
                ));
                
            }else{
                $data = $this->Catalog_product_branches->find('all', array(
                    'conditions' => array('location_id' =>$copy_from_store, 'status' => 1),
                    'order' => array(
                        'id' => 'DESC' 
                    )
                ));
            }
            
        
            $locationname = $this->Location->field('name', array('id' => $current_store_id));
            $saveData = [];
            foreach ($data as $item) {
                $saveData[] = [
                    'location_id' => $current_store_id,       
                    'location_name' => $locationname,
                    'product_id' => $item['Catalog_product_branches']['product_id'],   
                    'product_name' => $item['Catalog_product_branches']['product_name'],   
                    'cat_id' => $item['Catalog_product_branches']['cat_id'],   
                    'cat_name' => $item['Catalog_product_branches']['cat_name'],   
                    'subcat_id' => $item['Catalog_product_branches']['subcat_id'],   
                    'subcat_name' => $item['Catalog_product_branches']['subcat_name'],   
                    'price' => $item['Catalog_product_branches']['price'],   
                    'unit' => $item['Catalog_product_branches']['unit'],   
                    'unit_name' => $item['Catalog_product_branches']['unit_name'],
                    'sync'=>0,
                    'local_sync'=>0
                ];  
            }
            if (!empty($saveData)) {

                if ($this->Catalog_product_branches->saveAll($saveData)) {
                    $this->Flash->success(__('Products copied successfully.'));
                    $this->redirect(array('action' => 'store_products','?'=>array('location_id'=>$current_store_id)));
                    $this->autoRender = false;
                } else {
                    $this->Flash->error(__('Products could not be copied. Please, try again.'));
                    $this->redirect(array('action' => 'store_products','?'=>array('location_id'=>$current_store_id)));
                }
                        
            } else {
                $this->Flash->success(__('No Products to copy from the selected store.'));
                $this->redirect(array('action' => 'store_products','?'=>array('location_id'=>$current_store_id)));
            }
        }
    }

    public function audit_export()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $id = $_REQUEST['id'] ?? 0;
        if (empty($id)) {
            throw new BadRequestException('Invalid Audit ID.');
        }
    
        // 🔹 Fetch main audit record
        $indents = $this->Audit_stock->query("SELECT * FROM pos_auditstock WHERE pos_audit_id = $id");
    
        if (empty($indents)) {
            $this->Session->setFlash('No audit found for this record.', 'flash_error');
            return $this->redirect(['action' => 'view_audit']);
        }
    
        $audit = $indents[0]['pos_auditstock'];
    
        // 🔹 Fetch audit items
        $items = $this->Audit_stock_items->query("
            SELECT * 
            FROM pos_auditstock_items 
            WHERE pos_audit_id = $id 
              AND status = 1
            ORDER BY sku_name ASC
        ");
    
        if (empty($items)) {
            $this->Session->setFlash('No audit items found for this record.', 'flash_error');
            return $this->redirect(['action' => 'view_audit', $id]);
        }
    
        // 🔹 Load PHPExcel
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);
    
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()
            ->setCreator("QuickMart Audit System")
            ->setLastModifiedBy("QuickMart")
            ->setTitle("Audit Stock Report")
            ->setSubject("Audit Stock Report")
            ->setDescription("Exported audit stock data.")
            ->setKeywords("audit stock excel")
            ->setCategory("Export File");
    
        $sheet = $objPHPExcel->setActiveSheetIndex(0);
    
        // 🔹 Header Info (Compact Layout)
        $sheet->setCellValue('A1', 'Audit ID:')
              ->setCellValueExplicit('B1', (string)$audit['pos_audit_id'], PHPExcel_Cell_DataType::TYPE_STRING)
              ->setCellValue('C1', 'Store Name:')
              ->setCellValue('D1', $audit['store_name']);
    
        $sheet->setCellValue('A2', 'Remarks:')
              ->setCellValue('B2', $audit['remarks'])
              ->setCellValue('C2', 'Audit Date:')
              ->setCellValue('D2', $audit['updateon']);
    
        // Format header info
        $sheet->getStyle('A1:D2')->getFont()->setBold(true)->setSize(10);
        $sheet->getStyle('A1:D2')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
    
        // 🔹 Table Headers (Row 4)
        $headers = [
            'Sr No.', 'SKU Name', 'Unit', 'Price',
             'Physical Stock','Opening Stock',
             'Purchase','Consumption','Damage',
            'Closing Stock','Variance', 'Amount', 'Percentage',
            'Audit From', 'Audit To'
        ];
    
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '4', $header);
            $sheet->getStyle($col . '4')->getFont()->setBold(true);
            $sheet->getStyle($col . '4')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
            $col++;
        }
    
        // 🔹 Fill Data Rows
        $row = 5;
        $count = 1;
        foreach ($items as $itm) {
            $data = $itm['pos_auditstock_items'];
            $opening = (float)$data['openingstock'];
            $variance = (float)$data['variance'];
            $price = (float)$data['sku_price'];
            $percentage = ($opening > 0) ? round(($variance / $opening) * 100, 2) : 0;
            
            $sheet->setCellValue("A$row", $count)
                  ->setCellValue("B$row", $data['sku_name'])
                  ->setCellValue("C$row", $data['sku_unit_name'])
                  ->setCellValue("D$row", $data['sku_price'])
                  ->setCellValue("E$row", (float)$data['physicalstock'])
                  ->setCellValue("F$row", $opening)
                  ->setCellValue("G$row", $data['purchased'])
                  ->setCellValue("H$row", $data['consumption'])
                  ->setCellValue("I$row", $data['damage'])
                  ->setCellValue("J$row", $data['closingstock'])
                  ->setCellValue("K$row", $variance)
                  ->setCellValue("L$row", $price * $variance)
                  ->setCellValue("M$row", $percentage . '%')
                  ->setCellValue("N$row", $data['auditfrom'])
                  ->setCellValue("O$row", $data['auditto']);
    
            $row++;
            $count++;
        }
    
        // 🔹 Auto-size columns
        foreach (range('A', 'J') as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }
    
        // 🔹 Sheet name and download setup
        $sheet->setTitle('Audit Report');
        $objPHPExcel->setActiveSheetIndex(0);
    
        // 🔹 Output headers
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Audit_Report_' . $id . '.xls"');
        header('Cache-Control: max-age=0');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');
    
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }
    
    
    // V2 Report section 

    public function purchaseorder_report()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate = date('Y-m-d', strtotime($endDate));
        }

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $store_id  = !empty($this->request->data['Search']['store']) ? $this->request->data['Search']['store'] : null;
        $vendor_id = !empty($this->request->data['Search']['vendor']) ? $this->request->data['Search']['vendor'] : null;
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $where = " WHERE direct_purchase = 0 and ipoi.status!=0
                AND ipo.created BETWEEN '$startDatetime' and  '$endDatetime'";

        if ($store_id) {
            $where .= " AND ipo.location_id = " . (int)$store_id;
        } elseif ($userRole != 'admin') {
            $where .= " AND ipo.location_id IN (" . $userLocationId . ")";
        }

        if ($vendor_id) {
            $where .= " AND ipo.vendor_id = " . (int)$vendor_id;
        }

        // $purchaseorders = $this->Inventory_purchase_order->query("
        //     SELECT 
        //         ipo.id,
        //         ipo.p_o_id,
        //         ipo.vendor_name AS vendor,
        //         ipo.location_name AS store_name,
        //         ipoi.sku_name AS name,
        //         ipoi.sku_price AS price,
        //         ipoi.sku_quantity AS quantity,
        //         ipoi.sku_unit_name AS unit,
        //         ipoi.sku_amount AS total_amount,
        //         ipo.created
        //     FROM inventory_purchase_order ipo
        //     LEFT JOIN inventory_purchase_order_items ipoi 
        //         ON ipo.p_o_id = ipoi.p_o_id
        //     $where
        //     ORDER BY ipo.id DESC
        // ");
        $purchaseorders = $this->Inventory_purchase_order->query("
            SELECT 
                    ipo.vendor_name AS vendor,
                    ipoi.sku_name AS name,
                    ipoi.sku_unit_name AS unit,
                    SUM(ipoi.sku_quantity) AS sku_total_qty,
                    SUM(ipoi.sku_amount) AS sku_total_amnt,
                    SUM(ipoi.approved_quantity) AS approved_total_qty,
                    SUM(ipoi.approved_amount) AS approved_total_amnt,
                    SUM(ipoi.processed_quantity) AS processed_total_qty,
                    SUM(ipoi.processed_amount) AS processed_total_amnt,
                    SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                    SUM(ipoi.stockin_amount) AS stockin_total_amnt
                FROM inventory_purchase_order ipo
                LEFT JOIN inventory_purchase_order_items ipoi 
                    ON ipo.p_o_id = ipoi.p_o_id
                $where
                GROUP BY ipo.vendor_name, ipoi.sku_name, ipoi.sku_unit_name
                ORDER BY ipo.vendor_name ASC, ipoi.sku_name ASC
        ");

        $conditions = [
            'status' => 1,
            'type'   => 'DC'
        ];

        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        $stores = $this->Location->find('all', ['conditions' => $conditions]);
        $vendors = $this->Inventory_vendor->find('list', [
            'conditions' => [
                'Inventory_vendor.status' => 1
            ],
            'fields' => ['Inventory_vendor.id', 'Inventory_vendor.company'],
            'order' => ['Inventory_vendor.company ASC']
        ]);

        $yourStartDateValue = $startDate . ' - ' . $endDate;

        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('stores', 'vendors', 'purchaseorders'));
    }


    public function purchaseorder_reportexport() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $store_id = $_GET['store'];
        $vendor_id = $_GET['vendor'];
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        
        $where = " WHERE ipo.direct_purchase = 0 AND ipo.created BETWEEN '$startDatetime' and  '$endDatetime' and ipoi.status!=0";

        if ($store_id) {
            $storeData = $this->Location->find('first', ['conditions' => ['id' => $store_id]]);
            $store_name = $storeData['Location']['name'];
            $where .= " AND ipo.location_id = " . $store_id;
        } else {
            $store_name = 'All Stores';
        }
        

        if ($vendor_id) {
            $vendorData = $this->Inventory_vendor->find('first', ['conditions' => ['id' => $vendor_id]]);
            $vendor_name = $vendorData['Inventory_vendor']['company'];
            $where .= " AND ipo.vendor_id = " . (int)$vendor_id;
        } else {
            $vendor_name = 'All Vendors';
        }
        
        $purchaseorders = $this->Inventory_purchase_order->query("
            SELECT 
                    ipo.vendor_name AS vendor,
                    ipoi.sku_name AS name,
                    ipoi.sku_unit_name AS unit,
                    SUM(ipoi.sku_quantity) AS sku_total_qty,
                    SUM(ipoi.sku_amount) AS sku_total_amnt,
                    SUM(ipoi.approved_quantity) AS approved_total_qty,
                    SUM(ipoi.approved_amount) AS approved_total_amnt,
                    SUM(ipoi.processed_quantity) AS processed_total_qty,
                    SUM(ipoi.processed_amount) AS processed_total_amnt,
                    SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                    SUM(ipoi.stockin_amount) AS stockin_total_amnt
                FROM inventory_purchase_order ipo
                LEFT JOIN inventory_purchase_order_items ipoi 
                    ON ipo.p_o_id = ipoi.p_o_id
                $where
                GROUP BY ipo.vendor_name, ipoi.sku_name, ipoi.sku_unit_name
                ORDER BY ipo.vendor_name ASC, ipoi.sku_name ASC
        ");


        $datas = [];
        foreach ($purchaseorders as $po) {
            $datas[] = [
                'name' => $po['ipoi']['name'],
                'vendor' => $po['ipo']['vendor'],
                'unit' => $po['ipoi']['unit'],
                'sku_total_qty' => $po[0]['sku_total_qty'],
                'sku_total_amnt' => $po[0]['sku_total_amnt'],
                'approved_total_qty' => $po[0]['approved_total_qty'],
                'approved_total_amnt' => $po[0]['approved_total_amnt'],
                'processed_total_qty' => $po[0]['processed_total_qty'],
                'processed_total_amnt' => $po[0]['processed_total_amnt'],
                'stockin_total_qty' => $po[0]['stockin_total_qty'],
                'stockin_total_amnt' => $po[0]['stockin_total_amnt']
                
            ];
        }

        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);

        if (PHP_SAPI == 'cli')
            die('This example should only be run from a Web Browser');

        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("Office 2007 XLSX Aether Document")
            ->setSubject("Office 2007 XLSX Aether Document")
            ->setDescription("Aether Export Data File.")
            ->setKeywords("office 2007 openxml php")
            ->setCategory("AetherPos Export Data File");

        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'PURCHASE ORDER REPORT FROM ' . $startdate . ' TO ' . $enddate);
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', 'SR. NO.');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B3', 'Name');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C3', 'Vendor');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D3', 'Unit');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E3', 'Initial Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F3', 'Initial Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G3', 'Approved Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H3', 'Approved Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I3', 'Processed Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J3', 'Processed Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('K3', 'Stockin Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('L3', 'Stockin Total Amount');

        $objPHPExcel->getActiveSheet()->getStyle("A1:L3")->getFont()->setBold(true);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:L1');

        $baseRow = 3;
        $r = 1;
        foreach ($datas as $dat) {
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A' . ($baseRow + $r), $r);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B' . ($baseRow + $r), $dat['name']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C' . ($baseRow + $r), $dat['vendor']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D' . ($baseRow + $r), $dat['unit']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E' . ($baseRow + $r), $dat['sku_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F' . ($baseRow + $r), $dat['sku_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G' . ($baseRow + $r), $dat['approved_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H' . ($baseRow + $r), $dat['approved_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I' . ($baseRow + $r), $dat['processed_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J' . ($baseRow + $r), $dat['processed_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('K' . ($baseRow + $r), $dat['stockin_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('L' . ($baseRow + $r), $dat['stockin_total_amnt']);
            $r++;
        }

        $objPHPExcel->getActiveSheet()->setTitle('Purchase Orders');
        $objPHPExcel->setActiveSheetIndex(0);

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="PURCHASE ORDER REPORT.xls"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');

        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    public function purchaseorder_reportpdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $store_id = $this->request->data['store'];
            $vendor_id = $this->request->data['vendor'];
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
            
            $where = " WHERE ipo.direct_purchase = 0 AND ipo.created BETWEEN '$startDatetime' and  '$endDatetime' and ipoi.status!=0";

            if ($store_id) {
                $storeData = $this->Location->find('first', ['conditions' => ['id' => $store_id]]);
                $store_name = $storeData['Location']['name'];
                $where .= " AND ipo.location_id = " . (int)$store_id;
            } else {
                $store_name = 'All Stores';
            }

            if ($vendor_id) {
                $vendorData = $this->Inventory_vendor->find('first', ['conditions' => ['id' => $vendor_id]]);
                $vendor_name = $vendorData['Inventory_vendor']['company'];
                $where .= " AND ipo.vendor_id = " . (int)$vendor_id;
            } else {
                $vendor_name = 'All Vendors';
            }

            
            $purchaseorders = $this->Inventory_purchase_order->query("
                SELECT 
                        ipo.vendor_name AS company,
                        ipoi.sku_name AS name,
                        ipoi.sku_unit_name AS unit,
                        SUM(ipoi.sku_quantity) AS sku_total_qty,
                        SUM(ipoi.sku_amount) AS sku_total_amnt,
                        SUM(ipoi.approved_quantity) AS approved_total_qty,
                        SUM(ipoi.approved_amount) AS approved_total_amnt,
                        SUM(ipoi.processed_quantity) AS processed_total_qty,
                        SUM(ipoi.processed_amount) AS processed_total_amnt,
                        SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                        SUM(ipoi.stockin_amount) AS stockin_total_amnt
                    FROM inventory_purchase_order ipo
                    LEFT JOIN inventory_purchase_order_items ipoi 
                        ON ipo.p_o_id = ipoi.p_o_id
                    $where
                    GROUP BY ipo.vendor_name, ipoi.sku_name, ipoi.sku_unit_name
                    ORDER BY ipo.vendor_name ASC, ipoi.sku_name ASC
            ");


            $datas = [];
            foreach ($purchaseorders as $po) {
                $datas[] = [
                    'name' => $po['ipoi']['name'],
                    'vendor' => $po['ipo']['company'],
                    'unit' => $po['ipoi']['unit'],
                    'sku_total_qty' => $po[0]['sku_total_qty'],
                    'sku_total_amnt' => $po[0]['sku_total_amnt'],
                    'approved_total_qty' => $po[0]['approved_total_qty'],
                    'approved_total_amnt' => $po[0]['approved_total_amnt'],
                    'processed_total_qty' => $po[0]['processed_total_qty'],
                    'processed_total_amnt' => $po[0]['processed_total_amnt'],
                    'stockin_total_qty' => $po[0]['stockin_total_qty'],
                    'stockin_total_amnt' => $po[0]['stockin_total_amnt']
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name', 'vendor_name'));
        }
    }

    
    public function purchase_item_ledger(){
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
        } else {
            $startdate = date('Y-m-d', strtotime($startDate));
            $enddate = date('Y-m-d', strtotime($endDate));
        }

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $item_id  = !empty($this->request->data['Search']['item']) ? $this->request->data['Search']['item'] : null;
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $where = " WHERE direct_purchase = 0 and ipoi.status!=0
                AND ipo.created BETWEEN '$startDatetime' AND '$endDatetime'";

        if ($item_id) {
            $where .= " AND ipoi.sku_id = " . $item_id;
        }


        
        $items = $this->Inventory_sku->query("SELECT id,name FROM inventory_skus WHERE status = 1 order by name ASC");

        
        $purchaseorders = $this->Inventory_purchase_order->query("
            SELECT 
                ipoi.sku_name AS name,
                ipoi.sku_unit_name AS unit,
                SUM(ipoi.sku_quantity) AS sku_total_qty,
                SUM(ipoi.sku_amount) AS sku_total_amnt,
                SUM(ipoi.approved_quantity) AS approved_total_qty,
                SUM(ipoi.approved_amount) AS approved_total_amnt,
                SUM(ipoi.processed_quantity) AS processed_total_qty,
                SUM(ipoi.processed_amount) AS processed_total_amnt,
                SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                SUM(ipoi.stockin_amount) AS stockin_total_amnt
                FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi 
                ON ipo.p_o_id = ipoi.p_o_id
            $where
            GROUP BY ipoi.sku_name, ipoi.sku_unit_name
            ORDER BY ipoi.sku_name ASC");


        $conditions = [
            'status' => 1,
            'type'   => 'DC'
        ];

        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }

        $stores = $this->Location->find('all', ['conditions' => $conditions]);

        $yourStartDateValue = $startDate . ' - ' . $endDate;

        $this->set('startdate', $yourStartDateValue);
        $this->set(compact('items', 'purchaseorders'));
    }

    
    public function purchaseitemledger_export() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $item_id = $_GET['item'];
        $itemname = $_GET['itemname'];
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $where = " WHERE ipo.direct_purchase = 0 and ipoi.status!=0 AND ipo.created BETWEEN '$startDatetime' AND '$endDatetime'";

        if ($item_id) {
            $item_name = $itemname;
            $where .= " AND ipoi.sku_id = " . $item_id;
        } else {
            $item_name = 'All Items';
        }
        
        $purchaseorders = $this->Inventory_purchase_order->query("
            SELECT 
                ipoi.sku_name AS name,
                ipoi.sku_unit_name AS unit,
                SUM(ipoi.sku_quantity) AS sku_total_qty,
                SUM(ipoi.sku_amount) AS sku_total_amnt,
                SUM(ipoi.approved_quantity) AS approved_total_qty,
                SUM(ipoi.approved_amount) AS approved_total_amnt,
                SUM(ipoi.processed_quantity) AS processed_total_qty,
                SUM(ipoi.processed_amount) AS processed_total_amnt,
                SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                SUM(ipoi.stockin_amount) AS stockin_total_amnt
                FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi 
                ON ipo.p_o_id = ipoi.p_o_id
            $where
            GROUP BY ipoi.sku_name, ipoi.sku_unit_name
            ORDER BY ipoi.sku_name ASC");

        $datas = [];
        foreach ($purchaseorders as $po) {
            $datas[] = [
                'name' => $po['ipoi']['name'],
                'unit' => $po['ipoi']['unit'],
                'sku_total_qty' => $po[0]['sku_total_qty'],
                'sku_total_amnt' => $po[0]['sku_total_amnt'],
                'approved_total_qty' => $po[0]['approved_total_qty'],
                'approved_total_amnt' => $po[0]['approved_total_amnt'],
                'processed_total_qty' => $po[0]['processed_total_qty'],
                'processed_total_amnt' => $po[0]['processed_total_amnt'],
                'stockin_total_qty' => $po[0]['stockin_total_qty'],
                'stockin_total_amnt' => $po[0]['stockin_total_amnt']
            ];
        }
        App::import('Vendor', 'PHPExcel/PHPExcel');
        error_reporting(0);
        ini_set('display_errors', TRUE);
        ini_set('display_startup_errors', TRUE);

        if (PHP_SAPI == 'cli')
            die('This example should only be run from a Web Browser');

        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")
            ->setLastModifiedBy("Aether")
            ->setTitle("Office 2007 XLSX Aether Document")
            ->setSubject("Office 2007 XLSX Aether Document")
            ->setDescription("Aether Export Data File.")
            ->setKeywords("office 2007 openxml php")
            ->setCategory("AetherPos Export Data File");

        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', 'PURCHASE ORDER REPORT FROM ' . $startDatetime . ' TO ' . $endDatetime);
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A3', 'SR. NO.');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B3', 'Name');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C3', 'Unit');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D3', 'Initial Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E3', 'Initial Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F3', 'Approved Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G3', 'Approved Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H3', 'Processed Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I3', 'Processed Total Amount');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J3', 'Stockin Quantity');
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue('K3', 'Stockin Total Amount');
        

        $objPHPExcel->getActiveSheet()->getStyle("A1:K3")->getFont()->setBold(true);
        $objPHPExcel->getActiveSheet()->mergeCells('A1:K1');

        $baseRow = 3;
        $r = 1;
        foreach ($datas as $dat) {
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A' . ($baseRow + $r), $r);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('B' . ($baseRow + $r), $dat['name']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('C' . ($baseRow + $r), $dat['unit']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('D' . ($baseRow + $r), $dat['sku_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('E' . ($baseRow + $r), $dat['sku_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('F' . ($baseRow + $r), $dat['approved_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('G' . ($baseRow + $r), $dat['approved_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('H' . ($baseRow + $r), $dat['processed_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('I' . ($baseRow + $r), $dat['processed_total_amnt']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('J' . ($baseRow + $r), $dat['stockin_total_qty']);
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue('K' . ($baseRow + $r), $dat['stockin_total_amnt']);
            $r++;
        }

        $objPHPExcel->getActiveSheet()->setTitle('Purchase Item Ledger');
        $objPHPExcel->setActiveSheetIndex(0);

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="PURCHASE ITEM LEDGER REPORT.xls"');
        header('Cache-Control: max-age=0');
        header('Cache-Control: max-age=1');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');
        header('Pragma: public');

        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $objWriter->save('php://output');
        exit;
    }

    
    public function purchaseitemledger_reportpdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $item_id = $this->request->data['item'];
            $itemname = $this->request->data['itemname'];
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $where = " WHERE ipo.direct_purchase = 0 and ipoi.status!=0 AND ipo.created BETWEEN '$startDatetime' AND '$endDatetime'";

            if ($item_id) {
                $item_name = $itemname;
                $where .= " AND ipoi.sku_id = " . $item_id;
            } else {
                $item_name = 'All Items';
            }

            $purchaseorders = $this->Inventory_purchase_order->query("
            SELECT 
                ipoi.sku_name AS name,
                ipoi.sku_unit_name AS unit,
                SUM(ipoi.sku_quantity) AS sku_total_qty,
                SUM(ipoi.sku_amount) AS sku_total_amnt,
                SUM(ipoi.approved_quantity) AS approved_total_qty,
                SUM(ipoi.approved_amount) AS approved_total_amnt,
                SUM(ipoi.processed_quantity) AS processed_total_qty,
                SUM(ipoi.processed_amount) AS processed_total_amnt,
                SUM(ipoi.stockin_quantity) AS stockin_total_qty,
                SUM(ipoi.stockin_amount) AS stockin_total_amnt
                FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi 
                ON ipo.p_o_id = ipoi.p_o_id
            $where
            GROUP BY ipoi.sku_name, ipoi.sku_unit_name
            ORDER BY ipoi.sku_name ASC");


            $datas = [];
            foreach ($purchaseorders as $po) {
                $datas[] = [
                    'name' => $po['ipoi']['name'],
                    'unit' => $po['ipoi']['unit'],
                    'sku_total_qty' => $po[0]['sku_total_qty'] ?? 0,
                    'sku_total_amnt' => $po[0]['sku_total_amnt'] ?? 0,
                    'approved_total_qty' => $po[0]['approved_total_qty'] ?? 0,
                    'approved_total_amnt' => $po[0]['approved_total_amnt'] ?? 0,
                    'processed_total_qty' => $po[0]['processed_total_qty'] ?? 0,
                    'processed_total_amnt' => $po[0]['processed_total_amnt'] ?? 0,
                    'stockin_total_qty' => $po[0]['stockin_total_qty'] ?? 0,
                    'stockin_total_amnt' => $po[0]['stockin_total_amnt'] ?? 0
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'item_name','startDatetime','endDatetime'));
        }
    }

    
    
        /**
     * Complimentary Detail - 
     */
    
    public function complimentary_detail() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $cashierFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $complimentaryData = $this->Order_orderhistory->query("
            SELECT 
                DATE(p.created) AS report_date,
                (SELECT name FROM locations WHERE id = t.store_id) AS store_name,
                t.orderno AS bill_no,
                (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id = t.reference_id AND h2.status = 2) AS bill_open_time,
                t.created AS bill_print_time,
                p.created AS bill_settle_time,
                (SELECT GROUP_CONCAT(DISTINCT(kot_number)) FROM order_orderhistories h3 WHERE h3.reference_id = t.reference_id AND h3.status = 2) AS kot_numbers,
                (SELECT MIN(created) FROM order_orderhistories h4 WHERE h4.reference_id = t.reference_id AND h4.status = 2) AS kot_print_time,
                (SELECT name FROM pos_printers WHERE id = h.kds) AS section,
                h.category_name AS category,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                h.table_number AS tableno,
                p.remarks AS offer_name,
                ROUND(h.price * h.quantity, 2) AS amount,
                (SELECT username FROM users WHERE id = t.cashier_id) AS user_name,
                h.remarks AS complimentary_comment,
                t.remarks AS complimentary_head,
                t.name AS customer_name,
                t.phone AS customer_phone,
                (SELECT GROUP_CONCAT(ut.remarks SEPARATOR '; ') FROM user_tracks ut WHERE ut.reference_id = t.reference_id AND ut.type IN ('nocharge','unbill') LIMIT 1) AS manager_remarks
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
            INNER JOIN order_payments p ON p.reference_id = h.reference_id AND p.status = 2 AND p.type = 7
            LEFT JOIN order_tables ot ON ot.number = h.table_number 
            WHERE h.status = 2 
              AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
              $cashierFilter
            ORDER BY p.created ASC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'complimentaryData', 'cashier_id'));
    }


    /**
     * Complimentary Detail - Excel export
    */
    public function complimentary_detail_export() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $excelDateRange = $startdate. ' ' .$enddate;
        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole!='admin' ){
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : " AND t.store_id IN (" . $userLocationId . ")";
        }else{
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $rows = $this->Order_orderhistory->query("
            SELECT 
                DATE(p.created) AS report_date,
                (SELECT name FROM locations WHERE id = t.store_id) AS deployment_name,
                t.orderno AS bill_no,
                (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id = t.reference_id AND h2.status = 2) AS bill_open_time,
                t.created AS bill_print_time,
                p.created AS bill_settle_time,
                (SELECT GROUP_CONCAT(DISTINCT(kot_number)) FROM order_orderhistories h3 WHERE h3.reference_id = t.reference_id AND h3.status = 2) AS kot_numbers,
                (SELECT MIN(created) FROM order_orderhistories h4 WHERE h4.reference_id = t.reference_id AND h4.status = 2) AS kot_print_time,
                (SELECT name FROM pos_printers WHERE id = h.kds) AS section,
                h.category_name AS category,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                h.table_number AS tableno,
                p.remarks AS offer_name,
                ROUND(h.price * h.quantity, 2) AS amount,
                (SELECT username FROM users WHERE id = t.cashier_id) AS user_name,
                h.remarks AS complimentary_comment,
                t.remarks AS complimentary_head,
                t.name AS name,
                t.phone AS phone
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
            INNER JOIN order_payments p ON p.reference_id = h.reference_id AND p.status = 2 AND p.type = 7
            LEFT JOIN order_tables ot ON ot.number = h.table_number 
            WHERE h.status = 2 
              AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
              $cashierFilter
            ORDER BY p.created ASC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Complimentary Detail");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Complimentary Detail');

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_orderhistory->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } 
        else{
            $storeName = 'All Stores';
        }

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'Complimentary Detail (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $headers = array(
            'Date','Store Name','Bill Number','Bill Open Time','Bill Print Time','Bill Settle Time',
            'KOT No','KOT Print Time','Section','Category','Item Name','Rate','Qty','Amount','Fixed Cost','TableNo','Constumer Name','Constumer Phone',
            'User Name','Discount User','Complimentry Offer','Compliment Comment','Complimentary Head'
        );
        $sheet->fromArray($headers, null, 'A5');

        $rowNum = 6;
        // echo "<pre/>";
        foreach($rows as $r){
            
            $d = $r[0];
            $t = $r['t'];
            $p = $r['p'];
            $h = $r['h'];
            $ot = $r['ot'];
            $sheet->setCellValue("A$rowNum", $d['report_date']);
            $sheet->setCellValue("B$rowNum", $d['deployment_name']);
            $sheet->setCellValue("C$rowNum", $t['bill_no'] ?? $t['bill_no']);
            $sheet->setCellValue("D$rowNum", $d['bill_open_time']);
            $sheet->setCellValue("E$rowNum", $t['bill_print_time']);
            $sheet->setCellValue("F$rowNum", $p['bill_settle_time']);
            $sheet->setCellValue("G$rowNum", $d['kot_numbers']);
            $sheet->setCellValue("H$rowNum", $d['kot_print_time']);
            $sheet->setCellValue("I$rowNum", $d['section']);
            $sheet->setCellValue("J$rowNum", $h['category']);
            $sheet->setCellValue("K$rowNum", $h['item_name']);
            $sheet->setCellValue("L$rowNum", $h['rate']);
            $sheet->setCellValue("M$rowNum", $h['qty']);
            $sheet->setCellValue("N$rowNum", $d['amount']);
            $sheet->setCellValue("O$rowNum", ''); //fixed cost 
        //          $sheet->setCellValue("P$rowNum", $ot['segment']);
            $sheet->setCellValue("P$rowNum", $h['tableno']);
            $sheet->setCellValue("Q$rowNum", $t['name']); //consumer
            $sheet->setCellValue("R$rowNum", $t['phone']); //consumer Phone
            $sheet->setCellValue("S$rowNum", $d['user_name']);
            $sheet->setCellValue("T$rowNum", $d['user_name']);
            $sheet->setCellValue("U$rowNum", $p['offer_name']);
            $sheet->setCellValue("V$rowNum", $h['complimentary_comment']);
            $sheet->setCellValue("W$rowNum", $t['complimentary_head']);
            $rowNum++;
        }
        
        $sheet->getStyle('A5:X5')->getFont()->setBold(true);

        foreach(range('A','X') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Complimentary_Detail.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    
    public function complimentary_detail_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $cashierFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }

            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $rows = $this->Order_orderhistory->query("
                SELECT 
                    DATE(p.created) AS report_date,
                    (SELECT name FROM locations WHERE id = t.store_id) AS deployment_name,
                    t.orderno AS bill_no,
                    (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id = t.reference_id AND h2.status = 2) AS bill_open_time,
                    t.created AS bill_print_time,
                    p.created AS bill_settle_time,
                    (SELECT GROUP_CONCAT(DISTINCT(kot_number)) FROM order_orderhistories h3 WHERE h3.reference_id = t.reference_id AND h3.status = 2) AS kot_numbers,
                    (SELECT MIN(created) FROM order_orderhistories h4 WHERE h4.reference_id = t.reference_id AND h4.status = 2) AS kot_print_time,
                    (SELECT name FROM pos_printers WHERE id = h.kds) AS section,
                    h.category_name AS category,
                    h.product_name AS item_name,
                    h.price AS rate,
                    h.quantity AS qty,
                    h.table_number AS tableno,
                    p.remarks AS offer_name,
                    ROUND(h.price * h.quantity, 2) AS amount,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS user_name,
                    h.remarks AS complimentary_comment,
                    t.remarks AS complimentary_head,
                    t.name AS name,
                    t.phone AS phone
                FROM order_orderhistories h
                INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
                INNER JOIN order_payments p ON p.reference_id = h.reference_id AND p.status = 2 AND p.type = 7
                LEFT JOIN order_tables ot ON ot.number = h.table_number 
                WHERE h.status = 2 
                AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
                $cashierFilter
                ORDER BY p.created ASC
            ");

            $datas = [];
            foreach ($rows as $r) {
                $d = $r[0];
                $t = $r['t'];
                $p = $r['p'];
                $h = $r['h'];
                $ot = $r['ot'];


                $datas[] = [
                    'report_date' => $d['report_date'],
                    'deployment_name' => $d['deployment_name'],
                    'bill_no' => $t['bill_no'],
                    'bill_open_time' => $d['bill_open_time'],
                    'bill_print_time' => $t['bill_print_time'],
                    'bill_settle_time' => $p['bill_settle_time'],
                    'kot_numbers' => $d['kot_numbers'],
                    'kot_print_time' => $d['kot_print_time'],
                    'section' => $d['section'],
                    'category' => $h['category'],
                    'item_name' => $h['item_name'],
                    'rate' => $h['rate'],
                    'qty' => $h['qty'],
                    'amount' => $d['amount'],
                    'tableno' => $h['tableno'],
                    'user_name' => $d['user_name'],
                    'offer_name' => $p['offer_name'],
                    'complimentary_comment' => $h['complimentary_comment'],
                    'complimentary_head' => $t['complimentary_head'],
                    'name' => $t['name'],
                    'phone' => $t['phone']
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name'));
            $this->render('complimentary_detail_pdf');
        }
    }



    /**
     * Reprint Report -
     */
    public function reprint_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $cashierFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }
        
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // reprint - when payment is created after transaction creation (indicating bill was reprinted)
        $reprintData = $this->Order_transaction->query("
            SELECT 
                DATE(COALESCE(p_max.created, t.created)) AS report_date,
                (SELECT name FROM locations WHERE id = t.store_id) AS deployment_name,
                t.orderno AS bill_no,
                t.id AS transaction_id,
                t.reference_id,
                t.created AS original_print_time,
                COALESCE(p_max.created, t.created) AS reprint_time,
                t.amount AS original_bill_amount,
                COALESCE(payment_total.total_amount, t.amount) AS reprint_bill_amount,
                (SELECT username FROM users WHERE id = t.cashier_id) AS originally_printed_by,
                COALESCE((SELECT username FROM users WHERE id = p_max.cashier_id), (SELECT username FROM users WHERE id = t.cashier_id)) AS user,
                COALESCE(t.name, (SELECT customer_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_name,
                COALESCE(t.phone, (SELECT customer_phone FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_number,
                COALESCE(t.remarks, 'NA') AS comment
            FROM order_transactions t
            LEFT JOIN (
                SELECT p1.reference_id, p1.created, p1.cashier_id
                FROM order_payments p1
                INNER JOIN (
                    SELECT reference_id, MAX(created) AS max_created
                    FROM order_payments
                    WHERE status = 2
                    GROUP BY reference_id
                ) p2 ON p1.reference_id = p2.reference_id AND p1.created = p2.max_created
                WHERE p1.status = 2
            ) p_max ON p_max.reference_id = t.reference_id
            LEFT JOIN (
                SELECT reference_id, SUM(amount) AS total_amount
                FROM order_payments
                WHERE status = 2
                GROUP BY reference_id
            ) payment_total ON payment_total.reference_id = t.reference_id
            WHERE t.status = 2 
            AND p_max.created IS NOT NULL
            AND p_max.created > DATE_ADD(t.created, INTERVAL 2 MINUTE)
            AND DATE(p_max.created) BETWEEN '$startDatetime' AND '$endDatetime'
            $cashierFilter
            ORDER BY p_max.created DESC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'reprintData', 'cashier_id'));
    }


    /**
     * Reprint Report - Excel export
     */
    public function reprint_report_export() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));        
        $excelDateRange = $startdate. ' ' .$enddate;

        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole!='admin' ){
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : " AND t.store_id IN (" . $userLocationId . ")";
        }else{
            $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_orderhistory->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } 
        else{
            $storeName = 'All Stores';
        }
        
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;



        $rows = $this->Order_transaction->query("
            SELECT 
                DATE(COALESCE(p_max.created, t.created)) AS report_date,
                (SELECT name FROM locations WHERE id = t.store_id) AS deployment_name,
                t.orderno AS bill_no,
                t.created AS original_print_time,
                COALESCE(p_max.created, t.created) AS reprint_time,
                t.amount AS original_bill_amount,
                COALESCE(payment_total.total_amount, t.amount) AS reprint_bill_amount,
                (SELECT username FROM users WHERE id = t.cashier_id) AS originally_printed_by,
                COALESCE((SELECT username FROM users WHERE id = p_max.cashier_id), (SELECT username FROM users WHERE id = t.cashier_id)) AS user,
                COALESCE(t.name, (SELECT customer_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_name,
                COALESCE(t.phone, (SELECT customer_phone FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_number,
                COALESCE(t.remarks, 'NA') AS comment
            FROM order_transactions t
            LEFT JOIN (
                SELECT p1.reference_id, p1.created, p1.cashier_id
                FROM order_payments p1
                INNER JOIN (
                    SELECT reference_id, MAX(created) AS max_created
                    FROM order_payments
                    WHERE status = 2
                    GROUP BY reference_id
                ) p2 ON p1.reference_id = p2.reference_id AND p1.created = p2.max_created
                WHERE p1.status = 2
            ) p_max ON p_max.reference_id = t.reference_id
            LEFT JOIN (
                SELECT reference_id, SUM(amount) AS total_amount
                FROM order_payments
                WHERE status = 2
                GROUP BY reference_id
            ) payment_total ON payment_total.reference_id = t.reference_id
            WHERE t.status = 2 
            AND p_max.created IS NOT NULL
            AND p_max.created > DATE_ADD(t.created, INTERVAL 2 MINUTE)
            AND DATE(p_max.created) BETWEEN '$startDatetime' AND '$endDatetime'
            $cashierFilter
            ORDER BY p_max.created DESC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Reprint Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Reprint');

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'Reprint_Report (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $headers = array(
            'Date','billNo','Originally Printed By','Re Print Time','Re Print Bill Amount',
            'Actual Print Time','Original Bill Amount','User','Comment','Customer','Customer Number'
        );
        $sheet->fromArray($headers, null, 'A5');

        $rowNum = 6;
        foreach($rows as $r){
            $row = $r[0];
            $t = $r['t'];
            $sheet->setCellValue("A$rowNum", $row['report_date']);
            $sheet->setCellValue("B$rowNum", $t['bill_no']);
            $sheet->setCellValue("C$rowNum", $row['originally_printed_by']);
            $sheet->setCellValue("D$rowNum", date('d-m-Y H:i:s A', strtotime($row['reprint_time'])));
            $sheet->setCellValue("E$rowNum", number_format($row['reprint_bill_amount'], 2));
            $sheet->setCellValue("F$rowNum", date('d-m-Y H:i:s A', strtotime($t['original_print_time'])));
            $sheet->setCellValue("G$rowNum", number_format($t['original_bill_amount'], 2));
            $sheet->setCellValue("H$rowNum", $row['user']);
            $sheet->setCellValue("I$rowNum", $row['comment']);
            $sheet->setCellValue("J$rowNum", $row['customer_name']);
            $sheet->setCellValue("K$rowNum", $row['customer_number']);
            $rowNum++;
        }

        
        $sheet->getStyle('A5:K5')->getFont()->setBold(true);

        foreach(range('A','K') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Reprint_Report.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    
    /**
     * Reprint Report - PDF export
     */
    public function reprint_report_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $cashierFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $cashierFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }
            
                
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            $rows = $this->Order_transaction->query("
                SELECT 
                    DATE(COALESCE(p_max.created, t.created)) AS report_date,
                    (SELECT name FROM locations WHERE id = t.store_id) AS deployment_name,
                    t.orderno AS bill_no,
                    t.created AS original_print_time,
                    COALESCE(p_max.created, t.created) AS reprint_time,
                    t.amount AS original_bill_amount,
                    COALESCE(payment_total.total_amount, t.amount) AS reprint_bill_amount,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS originally_printed_by,
                    COALESCE((SELECT username FROM users WHERE id = p_max.cashier_id), (SELECT username FROM users WHERE id = t.cashier_id)) AS user,
                    COALESCE(t.name, (SELECT customer_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_name,
                    COALESCE(t.phone, (SELECT customer_phone FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), 'NA') AS customer_number,
                    COALESCE(t.remarks, 'NA') AS comment
                FROM order_transactions t
                LEFT JOIN (
                    SELECT reference_id, MAX(created) AS created, cashier_id
                    FROM order_payments
                    WHERE status = 2
                    GROUP BY reference_id, cashier_id
                ) p_max ON p_max.reference_id = t.reference_id
                LEFT JOIN (
                    SELECT reference_id, SUM(amount) AS total_amount
                    FROM order_payments
                    WHERE status = 2
                    GROUP BY reference_id
                ) payment_total ON payment_total.reference_id = t.reference_id
                WHERE t.status = 2 
                AND p_max.created IS NOT NULL
                AND p_max.created > DATE_ADD(t.created, INTERVAL 2 MINUTE)
                AND DATE(p_max.created) BETWEEN '$startDatetime' AND '$endDatetime'
                $cashierFilter
                ORDER BY p_max.created DESC
            ");

            $datas = [];
            foreach ($rows as $r) {
                $row = $r[0];
                $t = $r['t'];
                $datas[] = [
                    'report_date' => $row['report_date'],
                    'deployment_name' => $row['deployment_name'],
                    'bill_no' => $t['bill_no'],
                    'originally_printed_by' => $row['originally_printed_by'],
                    'reprint_time' => $row['reprint_time'],
                    'reprint_bill_amount' => $row['reprint_bill_amount'],
                    'original_print_time' => $t['original_print_time'],
                    'original_bill_amount' => $t['original_bill_amount'],
                    'user' => $row['user'],
                    'comment' => $row['comment'],
                    'customer_name' => $row['customer_name'],
                    'customer_number' => $row['customer_number']
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name'));
            $this->render('reprint_report_pdf');
        }
    }

     /**
     * Bill & KOT Delete Report - 
     */
    public function bill_kot_delete_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        // Allowed stores
        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        // Item (KOT) delete rows
        $kotDeleted = $this->Order_orderhistory->query("
            SELECT 
                DATE(h.created) AS report_date,
                t.orderno AS bill_no,
                h.kot_number AS kot_no,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                ROUND(h.total_tax,2) AS total_tax_value,
                h.table_number AS table_no,
                h.remarks AS comment,
                (SELECT username FROM users WHERE id = h.cashier_id) AS username,
                (SELECT username FROM users WHERE id = h.cashier_id) AS delete_user,
                (SELECT username FROM users WHERE id = t.cashier_id) AS settle_user,
                (SELECT name FROM locations WHERE id = t.store_id) AS server,
                COALESCE(t.name,'') AS customer_name,
                COALESCE(t.phone,'') AS customer_mobile,
                '' AS customer_address,
                'Item Delete' AS delete_type,
                CASE WHEN EXISTS (SELECT 1 FROM order_payments p WHERE p.reference_id=t.reference_id AND p.status=2) THEN 'After Settlement' ELSE 'Before Settlement' END AS bill_settlement_status,
                (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id=t.reference_id AND h2.status IN (0,1,2)) AS order_time,
                h.created AS delete_time
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id
            WHERE h.status = 0
              AND DATE(h.created) BETWEEN '$startdate' AND '$enddate'
              $storeFilter
        ");
        

        // Bill delete rows
        $billDeleted = $this->Order_transaction->query("
            SELECT 
                DATE(t.created) AS report_date,
                t.orderno AS bill_no,
                '' AS kot_no,
                '' AS item_name,
                0 AS rate,
                0 AS qty,
                ROUND(t.total_tax,2) AS total_tax_value,
                t.table_number AS table_no,
                t.remarks AS comment,
                (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                (SELECT username FROM users WHERE id = t.cashier_id) AS delete_user,
                '' AS settle_user,
                (SELECT name FROM locations WHERE id = t.store_id) AS server,
                COALESCE(t.name,'') AS customer_name,
                COALESCE(t.phone,'') AS customer_mobile,
                '' AS customer_address,
                'Bill Delete' AS delete_type,
                'Before Settlement' AS bill_settlement_status,
                t.created AS order_time,
                t.created AS delete_time
            FROM order_transactions t
            WHERE t.status = 0
              AND DATE(t.created) BETWEEN '$startdate' AND '$enddate'
              $storeFilter
        ");

        $rows = array_merge($kotDeleted, $billDeleted);

        $this->set(compact('users', 'yourStartDateValue', 'rows', 'cashier_id'));
    }

    /**
     * Bill & KOT Delete Report - Excel
     */
    public function bill_kot_delete_report_export() {
        $date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        
        $excelDateRange = $startdate. ' ' .$enddate;

        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole!='admin' ){
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : " AND t.store_id IN (" . $userLocationId . ")";
        }else{
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_orderhistory->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } 
        else{
            $storeName = 'All Stores';
        }
        
        $kotDeleted = $this->Order_orderhistory->query("
            SELECT 
                DATE(h.created) AS report_date,
                t.orderno AS bill_no,
                h.kot_number AS kot_no,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                ROUND(h.price * h.quantity, 2) AS total,
                h.table_number AS table_no,
                h.remarks AS comment,
                (SELECT username FROM users WHERE id = h.cashier_id) AS username,
                (SELECT username FROM users WHERE id = h.cashier_id) AS delete_user,
                (SELECT username FROM users WHERE id = t.cashier_id) AS settle_user,
                (SELECT name FROM locations WHERE id = t.store_id) AS server,
                COALESCE(t.name,'NA') AS customer_name,
                COALESCE(t.phone,'NA') AS customer_mobile,
                COALESCE(t.address,'NA') AS customer_address,
                'Item Delete' AS delete_type,
                CASE WHEN EXISTS (SELECT 1 FROM order_payments p WHERE p.reference_id=t.reference_id AND p.status=2) THEN 'Void After Settlement' ELSE 'Void Before Settlement' END AS bill_settlement_status,
                (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id=t.reference_id AND h2.status IN (0,1,2)) AS order_time,
                h.created AS delete_time,
                COALESCE((SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2), t.created) AS bill_close_time,
                '' AS tab_name
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id
            WHERE h.status = 0
              AND DATE(h.created) BETWEEN '$startdate' AND '$enddate'
              $storeFilter
        ");

        $billDeleted = $this->Order_transaction->query("
            SELECT 
                DATE(t.created) AS report_date,
                t.orderno AS bill_no,
                '' AS kot_no,
                '' AS item_name,
                0 AS rate,
                0 AS qty,
                0 AS total,
                t.table_number AS table_no,
                t.remarks AS comment,
                (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                (SELECT username FROM users WHERE id = t.cashier_id) AS delete_user,
                '' AS settle_user,
                (SELECT name FROM locations WHERE id = t.store_id) AS server,
                COALESCE(t.name,'NA') AS customer_name,
                COALESCE(t.phone,'NA') AS customer_mobile,
                COALESCE(t.address,'NA') AS customer_address,
                'Bill Delete' AS delete_type,
                'Void Before Settlement' AS bill_settlement_status,
                t.created AS order_time,
                t.created AS delete_time,
                t.created AS bill_close_time,
                '' AS tab_name
            FROM order_transactions t
            WHERE t.status = 0
              AND DATE(t.created) BETWEEN '$startdate' AND '$enddate'
              $storeFilter
        ");

        // Process and group KOT deleted items
        $groupedData = [];
        foreach($kotDeleted as $r){
            $d = $r[0];
            $t = isset($r['t']) ? $r['t'] : [];
            $h = isset($r['h']) ? $r['h'] : [];
            
            $billNo = $t['bill_no'] ?? $d['bill_no'];
            $billCloseTime = $d['bill_close_time'] ?? '';
            $key = $billNo . '_' . $billCloseTime;
            
            if(!isset($groupedData[$key])){
                $groupedData[$key] = [
                    'bill_no' => $billNo,
                    'bill_close_time' => $billCloseTime,
                    'items' => []
                ];
            }
            
            $groupedData[$key]['items'][] = [
                'd' => $d,
                't' => $t,
                'h' => $h
            ];
        }
        
        // Process and group Bill deleted items
        foreach($billDeleted as $r){
            $d = $r[0];
            $t = isset($r['t']) ? $r['t'] : [];
            
            $billNo = $t['bill_no'] ?? $d['bill_no'];
            $billCloseTime = $d['bill_close_time'] ?? '';
            $key = $billNo . '_' . $billCloseTime;
            
            if(!isset($groupedData[$key])){
                $groupedData[$key] = [
                    'bill_no' => $billNo,
                    'bill_close_time' => $billCloseTime,
                    'items' => []
                ];
            }
            
            $groupedData[$key]['items'][] = [
                'd' => $d,
                't' => $t,
                'h' => []
            ];
        }
        
        // Sort grouped data by bill number and bill close time
        uasort($groupedData, function($a, $b) {
            $billCompare = strcmp($a['bill_no'], $b['bill_no']);
            if ($billCompare !== 0) {
                return $billCompare;
            }
            return strcmp($a['bill_close_time'], $b['bill_close_time']);
        });

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Bill & KOT Delete Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Delete Report');

        
        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'KOT_Delete_History_combined(' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $headers = array(
            'KOT Number','Item','Order Time','Delete Time','Rate','Quantity','Total',
            'Tab Name','Table No.','Comment','Username','Deletion User','Settle User','Server',
            'Customer Name','Customer Mobile','Customer Address','Type','Bill Settlement Status'
        );
        $sheet->fromArray($headers, null, 'A5');

        // Style headers
        $headerStyle = $sheet->getStyle('A5:S5');
        $headerStyle->getFont()->setBold(true);
        $headerStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
        $headerStyle->getFill()->getStartColor()->setRGB('E0E0E0');

        $rowNum = 6;
        
        foreach($groupedData as $group){
            $billNo = $group['bill_no'];
            $billCloseTime = $group['bill_close_time'];
            $items = $group['items'];
            
            // Add bill header row
            $closeTimeFormatted = !empty($billCloseTime) ? date('h:i:s A', strtotime($billCloseTime)) : '';
            $sheet->setCellValue("A$rowNum", "Bill Number: $billNo Bill Close Time: $closeTimeFormatted");
            $sheet->mergeCells("A$rowNum:S$rowNum");
            $billHeaderStyle = $sheet->getStyle("A$rowNum");
            $billHeaderStyle->getFont()->setBold(true);
            $billHeaderStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
            $billHeaderStyle->getFill()->getStartColor()->setRGB('D0D0D0');
            $rowNum++;
            
            $billTotal = 0;
            
            // Add item rows
            foreach($items as $item){
                $d = $item['d'];
                $t = $item['t'];
                $h = $item['h'];
                
                $kotNo = $h['kot_no'] ?? $d['kot_no'] ?? '';
                $itemName = $h['item_name'] ?? $d['item_name'] ?? '';
                $orderTime = $d['order_time'] ?? '';
                $deleteTime = $h['delete_time'] ?? $d['delete_time'] ?? '';
                $rate = $h['rate'] ?? $d['rate'] ?? 0;
                $qty = $h['qty'] ?? $d['qty'] ?? 0;
                $total = $d['total'] ?? ($rate * $qty);
                $tabName = $d['tab_name'] ?? '';
                $tableNo = $h['table_no'] ?? $d['table_no'] ?? '';
                $comment = $h['comment'] ?? $d['comment'] ?? '';
                $username = $d['username'] ?? '';
                $deleteUser = $d['delete_user'] ?? '';
                $settleUser = $d['settle_user'] ?? '';
                $server = $d['server'] ?? '';
                $customerName = $d['customer_name'] ?? 'NA';
                $customerMobile = $d['customer_mobile'] ?? 'NA';
                $customerAddress = $d['customer_address'] ?? 'NA';
                $deleteType = $d['delete_type'] ?? '';
                $billSettlementStatus = $d['bill_settlement_status'] ?? '';
                
                $billTotal += (float)$total;
                
                $sheet->setCellValue("A$rowNum", $kotNo);
                $sheet->setCellValue("B$rowNum", $itemName);
                $sheet->setCellValue("C$rowNum", !empty($orderTime) ? date('d-m-Y h:i:s A', strtotime($orderTime)) : '');
                $sheet->setCellValue("D$rowNum", !empty($deleteTime) ? date('d-m-Y h:i:s A', strtotime($deleteTime)) : '');
                $sheet->setCellValue("E$rowNum", number_format($rate, 2));
                $sheet->setCellValue("F$rowNum", $qty);
                $sheet->setCellValue("G$rowNum", number_format($total, 2));
                $sheet->setCellValue("H$rowNum", $tabName);
                $sheet->setCellValue("I$rowNum", $tableNo);
                $sheet->setCellValue("J$rowNum", $comment);
                $sheet->setCellValue("K$rowNum", $username);
                $sheet->setCellValue("L$rowNum", $deleteUser);
                $sheet->setCellValue("M$rowNum", $settleUser);
                $sheet->setCellValue("N$rowNum", $server);
                $sheet->setCellValue("O$rowNum", $customerName);
                $sheet->setCellValue("P$rowNum", $customerMobile);
                $sheet->setCellValue("Q$rowNum", $customerAddress);
                $sheet->setCellValue("R$rowNum", $deleteType);
                $sheet->setCellValue("S$rowNum", $billSettlementStatus);
                $rowNum++;
            }
            
            // Add bill total row
            $sheet->setCellValue("A$rowNum", "Bill Total");
            $sheet->setCellValue("G$rowNum", number_format($billTotal, 2));
            $billTotalStyle = $sheet->getStyle("A$rowNum:S$rowNum");
            $billTotalStyle->getFont()->setBold(true);
            $billTotalStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
            $billTotalStyle->getFill()->getStartColor()->setRGB('F0F0F0');
            $rowNum++;
        }
        
        foreach(range('A','S') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Bill_KOT_Delete_Report.xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    /**
     * Bill & KOT Delete Report - PDF
     */
    public function bill_kot_delete_report_pdf() {

        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $storeFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }

            $kotDeleted = $this->Order_orderhistory->query("
                SELECT 
                    DATE(h.created) AS report_date,
                    t.orderno AS bill_no,
                    h.kot_number AS kot_no,
                    h.product_name AS item_name,
                    h.price AS rate,
                    h.quantity AS qty,
                    ROUND(h.price * h.quantity, 2) AS total,
                    h.table_number AS table_no,
                    h.remarks AS comment,
                    (SELECT username FROM users WHERE id = h.cashier_id) AS username,
                    (SELECT username FROM users WHERE id = h.cashier_id) AS delete_user,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS settle_user,
                    (SELECT name FROM locations WHERE id = t.store_id) AS server,
                    COALESCE(t.name,'NA') AS customer_name,
                    COALESCE(t.phone,'NA') AS customer_mobile,
                    COALESCE(t.address,'NA') AS customer_address,
                    'Item Delete' AS delete_type,
                    CASE WHEN EXISTS (SELECT 1 FROM order_payments p WHERE p.reference_id=t.reference_id AND p.status=2)
                        THEN 'Void After Settlement'
                        ELSE 'Void Before Settlement' END AS bill_settlement_status,
                    (SELECT MIN(created) FROM order_orderhistories h2 WHERE h2.reference_id=t.reference_id AND h2.status IN (0,1,2)) AS order_time,
                    h.created AS delete_time,
                    COALESCE((SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2), t.created) AS bill_close_time,
                    '' AS tab_name
                FROM order_orderhistories h
                INNER JOIN order_transactions t ON t.reference_id = h.reference_id
                WHERE h.status = 0
                AND DATE(h.created) BETWEEN '$startdate' AND '$enddate'
                $storeFilter
            ");

            
            $billDeleted = $this->Order_transaction->query("
                SELECT 
                    DATE(t.created) AS report_date,
                    t.orderno AS bill_no,
                    '' AS kot_no,
                    '' AS item_name,
                    0 AS rate,
                    0 AS qty,
                    0 AS total,
                    t.table_number AS table_no,
                    t.remarks AS comment,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS delete_user,
                    '' AS settle_user,
                    (SELECT name FROM locations WHERE id = t.store_id) AS server,
                    COALESCE(t.name,'NA') AS customer_name,
                    COALESCE(t.phone,'NA') AS customer_mobile,
                    COALESCE(t.address,'NA') AS customer_address,
                    'Bill Delete' AS delete_type,
                    'Void Before Settlement' AS bill_settlement_status,
                    t.created AS order_time,
                    t.created AS delete_time,
                    t.created AS bill_close_time,
                    '' AS tab_name
                FROM order_transactions t
                WHERE t.status = 0
                AND DATE(t.created) BETWEEN '$startdate' AND '$enddate'
                $storeFilter
            ");

            
            $datas = array_merge($kotDeleted, $billDeleted);
            $this->set(compact('startdate', 'enddate', 'datas', 'store_name'));
            $this->render('bill_kot_delete_report_pdf');
        }
    }



    /**
     * Removed Service Charges Report - filter screen
     */
    public function removed_service_charges_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        // Query for removed service charges (taxes with status = 0)
        // Find taxes that were removed - taxes with status 0 that exist for transactions
        $removedChargesData = $this->Order_tax->query("
            SELECT 
                DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) AS report_date,
                t.orderno AS bill_no,
                CONCAT(COALESCE(tax.tax_name, ''), ' @ ', COALESCE(tax.tax_percentage, 0)) AS tax_name,
                ROUND(tax.tax_value, 2) AS tax_amount,
                COALESCE(tax.modified, tax.created, t.modified, t.created) AS removed_at,
                t.created AS bill_print_time,
                COALESCE((SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2), '') AS settled_time,
                CONCAT((SELECT username FROM users WHERE id = t.cashier_id), '(', (SELECT name FROM users WHERE id = t.cashier_id), ')') AS removed_by_user,
                (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                COALESCE((SELECT waiter_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), '') AS waiter_username,
                COALESCE(t.name, '') AS customer_name,
                COALESCE(t.phone, '') AS customer_mobile,
                COALESCE(t.remarks, '') AS edit_bill_comment,
                tax.reference_id,
                tax.tax_id
            FROM order_tax tax
            INNER JOIN order_transactions t ON t.reference_id = tax.reference_id
            WHERE tax.status = 0
            AND tax.tax_name IS NOT NULL
            AND tax.tax_name != ''
            AND DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) BETWEEN '$startdate' AND '$enddate'
            $storeFilter
            GROUP BY tax.id, tax.reference_id, tax.tax_id
            ORDER BY report_date DESC, removed_at DESC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'removedChargesData', 'cashier_id'));
    }


    /**
     * Removed Service Charges Report - Excel export
     */
    public function removed_service_charges_report_export() {
        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));        
        $excelDateRange = $startdate. ' ' .$enddate;

        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if($userRole!='admin' ){
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : " AND t.store_id IN (" . $userLocationId . ")";
        }else{
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_orderhistory->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } 
        else{
            $storeName = 'All Stores';
        }

        $rows = $this->Order_tax->query("
            SELECT 
                DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) AS report_date,
                t.orderno AS bill_no,
                CONCAT(COALESCE(tax.tax_name, ''), ' @ ', COALESCE(tax.tax_percentage, 0)) AS tax_name,
                ROUND(tax.tax_value, 2) AS tax_amount,
                COALESCE(tax.modified, tax.created, t.modified, t.created) AS removed_at,
                t.created AS bill_print_time,
                COALESCE((SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2), '') AS settled_time,
                CONCAT((SELECT username FROM users WHERE id = t.cashier_id), '(', (SELECT name FROM users WHERE id = t.cashier_id), ')') AS removed_by_user,
                (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                COALESCE((SELECT waiter_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), '') AS waiter_username,
                COALESCE(t.name, '') AS customer_name,
                COALESCE(t.phone, '') AS customer_mobile,
                COALESCE(t.remarks, '') AS edit_bill_comment,
                tax.reference_id,
                tax.tax_id
            FROM order_tax tax
            INNER JOIN order_transactions t ON t.reference_id = tax.reference_id
            WHERE tax.status = 0
            AND tax.tax_name IS NOT NULL
            AND tax.tax_name != ''
            AND DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) BETWEEN '$startdate' AND '$enddate'
            $storeFilter
            GROUP BY tax.id, tax.reference_id, tax.tax_id
            ORDER BY report_date DESC, removed_at DESC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Removed Service Charges Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Removed_Service_Charges_Report');

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'Removed_Taxes/Charges_Report (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        // Headers
        $headers = array(
            'Date','Bill Number','Tax Name','Tax Amount','Removed At','Bill Print Time',
            'Settled Time','Removed By(User Id)','Username','Waiter Username',
            'Customer Name','Customer Mobile','Edit Bill Comment'
        );
        $sheet->fromArray($headers, null, 'A5');

        // Style headers
        $headerStyle = $sheet->getStyle('A5:M5');
        $headerStyle->getFont()->setBold(true);
        $headerStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
        $headerStyle->getFill()->getStartColor()->setRGB('E0E0E0');

        $rowNum = 6;
        $currentDate = '';
        $dayTotalAmount = 0;
        $dayBillCount = 0;
        $processedBills = []; 

        foreach($rows as $r){
            $row = $r[0];
            $t = $r['t'];
            $billNo = $t['bill_no'];
            $reportDate = $row['report_date'];
            $billKey = $reportDate . '_' . $billNo;
            
            if($currentDate != '' && $currentDate != $reportDate) {
                
                $sheet->setCellValue("A$rowNum", "Day Total");
                $sheet->setCellValue("B$rowNum", "Bill Count: $dayBillCount");
                $sheet->setCellValue("D$rowNum", number_format($dayTotalAmount, 2));
                $dayTotalStyle = $sheet->getStyle("A$rowNum:D$rowNum");
                $dayTotalStyle->getFont()->setBold(true);
                $dayTotalStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
                $dayTotalStyle->getFill()->getStartColor()->setRGB('F0F0F0');
                $rowNum++;
                
                $dayTotalAmount = 0;
                $dayBillCount = 0;
                $processedBills = [];
            }
            
            $currentDate = $reportDate;
            $dayTotalAmount += (float)$row['tax_amount'];
            
            if (!in_array($billKey, $processedBills)) {
                $dayBillCount++;
                $processedBills[] = $billKey;
            }
            
            $sheet->setCellValue("A$rowNum", $reportDate);
            $sheet->setCellValue("B$rowNum", $billNo);
            $sheet->setCellValue("C$rowNum", $row['tax_name']);
            $sheet->setCellValue("D$rowNum", number_format($row['tax_amount'], 2));
            $sheet->setCellValue("E$rowNum", date('H:i:s A', strtotime($row['removed_at'])));
            $sheet->setCellValue("F$rowNum", date('H:i:s A', strtotime($t['bill_print_time'])));
            $sheet->setCellValue("G$rowNum", !empty($row['settled_time']) ? date('H:i:s A', strtotime($row['settled_time'])) : '-');
            $sheet->setCellValue("H$rowNum", $row['removed_by_user']);
            $sheet->setCellValue("I$rowNum", $row['username']);
            $sheet->setCellValue("J$rowNum", $row['waiter_username'] ?: '-');
            $sheet->setCellValue("K$rowNum", $row['customer_name'] ?: '-');
            $sheet->setCellValue("L$rowNum", $row['customer_mobile'] ?: '-');
            $sheet->setCellValue("M$rowNum", $row['edit_bill_comment'] ?: '-');
            $rowNum++;
        }
        
        if($dayBillCount > 0) {
            $sheet->setCellValue("A$rowNum", "Day Total");
            $sheet->setCellValue("B$rowNum", "Bill Count: $dayBillCount");
            $sheet->setCellValue("D$rowNum", number_format($dayTotalAmount, 2));
            $dayTotalStyle = $sheet->getStyle("A$rowNum:D$rowNum");
            $dayTotalStyle->getFont()->setBold(true);
            $dayTotalStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
            $dayTotalStyle->getFill()->getStartColor()->setRGB('F0F0F0');
            $rowNum++;
        }
        
        $sheet->getStyle('A5:M5')->getFont()->setBold(true);

        foreach(range('A','M') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Removed_Service_Charges_Report(' . $startdate . '--' . $enddate . ').xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }

    
    /**
     * Removed Service Charges Report - PDF export
     */
    public function removed_service_charges_report_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $storeFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }

            $rows = $this->Order_tax->query("
                SELECT 
                    DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) AS report_date,
                    t.orderno AS bill_no,
                    CONCAT(COALESCE(tax.tax_name, ''), ' @ ', COALESCE(tax.tax_percentage, 0)) AS tax_name,
                    ROUND(tax.tax_value, 2) AS tax_amount,
                    COALESCE(tax.modified, tax.created, t.modified, t.created) AS removed_at,
                    t.created AS bill_print_time,
                    COALESCE((SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2), '') AS settled_time,
                    CONCAT((SELECT username FROM users WHERE id = t.cashier_id), '(', (SELECT name FROM users WHERE id = t.cashier_id), ')') AS removed_by_user,
                    (SELECT username FROM users WHERE id = t.cashier_id) AS username,
                    COALESCE((SELECT waiter_name FROM order_tables WHERE reference_id = t.reference_id LIMIT 1), '') AS waiter_username,
                    COALESCE(t.name, '') AS customer_name,
                    COALESCE(t.phone, '') AS customer_mobile,
                    COALESCE(t.remarks, '') AS edit_bill_comment,
                    tax.reference_id,
                    tax.tax_id
                FROM order_tax tax
                INNER JOIN order_transactions t ON t.reference_id = tax.reference_id
                WHERE tax.status = 0
                AND tax.tax_name IS NOT NULL
                AND tax.tax_name != ''
                AND DATE(COALESCE(tax.modified, tax.created, t.modified, t.created)) BETWEEN '$startdate' AND '$enddate'
                $storeFilter
                GROUP BY tax.id, tax.reference_id, tax.tax_id
                ORDER BY report_date DESC, removed_at DESC
            ");

            $datas = [];
            $dayTotals = [];
            
            foreach ($rows as $r) {
                $row = $r[0];
                $tax = isset($r['tax']) ? $r['tax'] : [];
                $t = isset($r['t']) ? $r['t'] : [];
                $ot = isset($r['ot']) ? $r['ot'] : [];
                
                $reportDate = $row['report_date'];
                
                if (!isset($dayTotals[$reportDate])) {
                    $dayTotals[$reportDate] = ['count' => 0, 'amount' => 0];
                }
                
                $dayTotals[$reportDate]['count']++;
                $dayTotals[$reportDate]['amount'] += (float)$row['tax_amount'];
                
                $datas[] = [
                    'report_date' => $reportDate,
                    'bill_no' => $t['bill_no'] ?? $row['bill_no'],
                    'tax_name' => $row['tax_name'],
                    'tax_amount' => $row['tax_amount'],
                    'removed_at' => $row['removed_at'],
                    'bill_print_time' => $row['bill_print_time'],
                    'settled_time' => $row['settled_time'],
                    'removed_by_user' => $row['removed_by_user'],
                    'username' => $row['username'],
                    'waiter_username' => $row['waiter_username'],
                    'customer_name' => $row['customer_name'],
                    'customer_mobile' => $row['customer_mobile'],
                    'edit_bill_comment' => $row['edit_bill_comment']
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name', 'dayTotals'));
            $this->render('removed_service_charges_report_pdf');
        }
    }



    /**
     * KOT Detail Report -
     */
    public function kot_detail_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
        // KOT line-items printed (status = 2) with transactional context
        $rows = $this->Order_orderhistory->query("
            SELECT 
                DATE(h.created) AS report_date,
                t.orderno AS bill_serial_number,
                t.remarks AS edit_bill_comment,
                h.kot_number AS kot_number,
                DATE(h.created) AS kot_date,
                TIME(h.created) AS kot_time,
                'NA' AS kot_comment,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                ROUND(h.price * h.quantity, 2) AS amount,
                COALESCE(h.remarks, '') AS item_comment
            FROM order_orderhistories h
            INNER JOIN order_transactions t 
                ON t.reference_id = h.reference_id AND t.status != 0
            WHERE h.status != 0
              AND h.created BETWEEN '$startDatetime' AND '$endDatetime 23:59:59'
              $storeFilter
            ORDER BY h.created ASC, t.orderno ASC, h.kot_number ASC, h.id ASC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'rows', 'cashier_id'));
    }


    /**
     * KOT Detail Report - Excel export
     */
    public function kot_detail_report_export() {
        $date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $excelDateRange = $startdate . ' ' . $enddate;
        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_orderhistory->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } else {
            $storeName = 'All Stores';
        }
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $rows = $this->Order_orderhistory->query("
            SELECT 
                DATE(h.created) AS report_date,
                t.orderno AS bill_serial_number,
                t.remarks AS edit_bill_comment,
                h.kot_number AS kot_number,
                DATE(h.created) AS kot_date,
                TIME(h.created) AS kot_time,
                'NA' AS kot_comment,
                h.product_name AS item_name,
                h.price AS rate,
                h.quantity AS qty,
                ROUND(h.price * h.quantity, 2) AS amount,
                COALESCE(h.remarks, '') AS item_comment
            FROM order_orderhistories h
            INNER JOIN order_transactions t 
                ON t.reference_id = h.reference_id AND t.status != 0
            WHERE h.status != 0
              AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
              $storeFilter
            ORDER BY h.created ASC, t.orderno ASC, h.kot_number ASC, h.id ASC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("KOT Detail Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('KOT_Detail_Report');

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'KOT Detail Report (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $headers = array(
            'Date','Bill Serial Number','Edit Bill Comment','KOT Number','KOT Date','KOT Time',
            'KOT Comment','Item Name','Rate','Quantity','Amount','Item Comment'
        );
        $sheet->fromArray($headers, null, 'A5');

        $rowNum = 6;
        $currentDate = '';
        $dayTotalAmount = 0;
        $grandTotalAmount = 0;

        foreach ($rows as $r) {
            $d = $r[0];
            $t = $r['t'];
            $h = $r['h'];
            $reportDate = $d['report_date'];

            if ($currentDate !== '' && $currentDate !== $reportDate) {
                $sheet->setCellValue("A$rowNum", "Day Total");
                $sheet->setCellValue("K$rowNum", number_format($dayTotalAmount, 2));
                $dayTotalStyle = $sheet->getStyle("A$rowNum:K$rowNum");
                $dayTotalStyle->getFont()->setBold(true);
                $rowNum++;
                $dayTotalAmount = 0;
            }

            $currentDate = $reportDate;
            $dayTotalAmount += (float)$d['amount'];
            $grandTotalAmount += (float)$d['amount'];

            $sheet->setCellValue("A$rowNum", $d['report_date']);
            $sheet->setCellValue("B$rowNum", $t['bill_serial_number']);
            $sheet->setCellValue("C$rowNum", $t['edit_bill_comment']);
            $sheet->setCellValue("D$rowNum", $h['kot_number']);
            $sheet->setCellValue("E$rowNum", $d['kot_date']);
            $sheet->setCellValue("F$rowNum", $d['kot_time']);
            $sheet->setCellValue("G$rowNum", $d['kot_comment']);
            $sheet->setCellValue("H$rowNum", $h['item_name']);
            $sheet->setCellValue("I$rowNum", $h['rate']);
            $sheet->setCellValue("J$rowNum", $h['qty']);
            $sheet->setCellValue("K$rowNum", $d['amount']);
            $sheet->setCellValue("L$rowNum", $d['item_comment']);
            $rowNum++;
        }

        if ($currentDate !== '') {
            $sheet->setCellValue("A$rowNum", "Day Total");
            $sheet->setCellValue("K$rowNum", number_format($dayTotalAmount, 2));
            $dayTotalStyle = $sheet->getStyle("A$rowNum:K$rowNum");
            $dayTotalStyle->getFont()->setBold(true);
            $rowNum++;
        }

        $sheet->setCellValue("A$rowNum", "Grand Total");
        $sheet->setCellValue("K$rowNum", number_format($grandTotalAmount, 2));
        $grandTotalStyle = $sheet->getStyle("A$rowNum:K$rowNum");
        $grandTotalStyle->getFont()->setBold(true);

        $sheet->getStyle('A5:L5')->getFont()->setBold(true);
        foreach (range('A', 'L') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="KOT_Detail_Report(' . $startdate . '--' . $enddate . ').xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }


    /**
     * KOT Detail Report - PDF export
     */
    public function kot_detail_report_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'] ?? (date('m/d/Y') . ' - ' . date('m/d/Y'));
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $storeFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;
            $rows = $this->Order_orderhistory->query("
                SELECT 
                    DATE(h.created) AS report_date,
                    t.orderno AS bill_serial_number,
                    t.remarks AS edit_bill_comment,
                    h.kot_number AS kot_number,
                    DATE(h.created) AS kot_date,
                    TIME(h.created) AS kot_time,
                    'NA' AS kot_comment,
                    h.product_name AS item_name,
                    h.price AS rate,
                    h.quantity AS qty,
                    ROUND(h.price * h.quantity, 2) AS amount,
                    COALESCE(h.remarks, '') AS item_comment
                FROM order_orderhistories h
                INNER JOIN order_transactions t 
                    ON t.reference_id = h.reference_id AND t.status != 0
                WHERE h.status != 0
                  AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
                  $storeFilter
                ORDER BY h.created ASC, t.orderno ASC, h.kot_number ASC, h.id ASC
            ");

            $datas = [];
            foreach ($rows as $r) {
                $d = $r[0];
                $t = $r['t'];
                $h = $r['h'];
                $datas[] = [
                    'report_date' => $d['report_date'],
                    'bill_serial_number' => $t['bill_serial_number'],
                    'edit_bill_comment' => $t['edit_bill_comment'],
                    'kot_number' => $h['kot_number'],
                    'kot_date' => $d['kot_date'],
                    'kot_time' => $d['kot_time'],
                    'kot_comment' => $d['kot_comment'],
                    'item_name' => $h['item_name'],
                    'rate' => $h['rate'],
                    'qty' => $h['qty'],
                    'amount' => $d['amount'],
                    'item_comment' => $d['item_comment']
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name'));
            $this->render('kot_detail_report_pdf');
        }
    }

    /**
     * Bill Item Detail Report - filter screen
     */
    public function bill_item_detail_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];

        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            if (!empty($userLocationIds)) {
                $conditions['id IN'] = array_map('trim', $userLocationIds);
            }
        }

        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            if (!empty($cashier_id)) {
                $storeFilter = " AND t.store_id=$cashier_id";
            } elseif (!empty($userLocationId)) {
                $storeFilter = " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = '';
            }
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Build dynamic tax columns (same logic as export/pdf)
        $taxesDistinct = $this->Order_tax->query("
            SELECT DISTINCT tax_name, tax_percentage
            FROM order_tax ot
            INNER JOIN order_orderhistories h ON h.reference_id = ot.reference_id
            INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
            WHERE h.status = 2
            AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
            AND ot.status = 2
            $storeFilter
        ");
        $taxColumns = [];
        foreach ($taxesDistinct as $td) {
            $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
            $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
            if ($name !== '') {
                $taxColumns[] = $name . "(" . $perc . "%)";
            }
        }
        sort($taxColumns);

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $rows = $this->Order_orderhistory->query("
            SELECT 
                COALESCE(NULLIF(TRIM(loc.print_line3), ''), 'NA') AS state,
                loc.name AS deployment,
                t.orderno AS bill_no,
                t.reference_id AS order_id,
                t.tokenno AS day_serial,
                DATE(t.created) AS bill_date,
                '' AS tab_name,
                h.table_number AS table_no,
                (SELECT MIN(created) FROM order_orderhistories ho WHERE ho.reference_id = t.reference_id AND ho.status IN (1,2)) AS open_time,
                COALESCE(pay.settled_time, t.created) AS close_time,
                h.category_name AS category,
                h.product_name AS item_name,
                h.product_id AS item_number,
                (SELECT name FROM pos_printers WHERE id = h.kds) AS item_section,
                CASE 
                    WHEN cp.food_type = 0 THEN 'Veg'
                    WHEN cp.food_type = 1 THEN 'Non Veg'
                    WHEN cp.food_type = 2 THEN 'Egg'
                    ELSE 'NA'
                END AS item_classification,
                ROUND(h.price, 2) AS rate,
                h.quantity AS qty,
                ROUND(h.price * h.quantity, 2) AS amount,
                ROUND(h.discount, 2) AS discount_amount,
                CASE WHEN h.price * h.quantity > 0 THEN ROUND((h.discount / (h.price * h.quantity)) * 100, 2) ELSE 0 END AS discount_percent,
                ROUND(COALESCE(tax.taxable_price, 0), 2) AS taxable_amount,
                ROUND(COALESCE(tax.total_tax_value, 0), 2) AS gst_total,
                ROUND(COALESCE(tax.sgst_amount, 0), 2) AS sgst_amount,
                ROUND(COALESCE(tax.cgst_amount, 0), 2) AS cgst_amount,
                COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0) AS service_charge_per_item,
                0 AS service_charge_tax,
                ROUND(
                    (h.price * h.quantity) - h.discount
                    + COALESCE(tax.total_tax_value, 0)
                    + COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0),
                    2
                ) AS net_amount,
                'POS' AS source,
                COALESCE(taxmap.tax_map, '') AS tax_map
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
            LEFT JOIN locations loc ON loc.id = t.store_id
            LEFT JOIN catalog_product cp ON cp.id = h.product_id
            LEFT JOIN (
                SELECT 
                    reference_id,
                    product_id,
                    MAX(taxable_price) AS taxable_price,
                    SUM(tax_value) AS total_tax_value,
                    SUM(CASE WHEN tax_name LIKE 'SGST%' THEN tax_value ELSE 0 END) AS sgst_amount,
                    SUM(CASE WHEN tax_name LIKE 'CGST%' THEN tax_value ELSE 0 END) AS cgst_amount
                FROM order_tax
                WHERE status != 0
                GROUP BY reference_id, product_id
            ) tax ON tax.reference_id = h.reference_id AND tax.product_id = h.product_id
            LEFT JOIN (
                SELECT 
                    reference_id,
                    MIN(created) AS settled_time
                FROM order_payments
                WHERE status = 2
                GROUP BY reference_id
            ) pay ON pay.reference_id = h.reference_id
            LEFT JOIN (
                SELECT reference_id, COUNT(*) AS item_count
                FROM order_orderhistories
                WHERE status = 2
                GROUP BY reference_id
            ) ic ON ic.reference_id = h.reference_id
            LEFT JOIN (
                SELECT reference_id, product_id, GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                FROM order_tax
                WHERE status = 2
                AND created BETWEEN '$startDatetime' AND '$endDatetime'
                GROUP BY reference_id, product_id
            ) taxmap ON taxmap.reference_id = h.reference_id AND taxmap.product_id = h.product_id
            WHERE h.status = 2
            AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
            $storeFilter
            ORDER BY t.created ASC, t.orderno ASC, h.id ASC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'rows', 'cashier_id', 'taxColumns'));
    }
    
    
    /**
     * Bill Item Detail Report - Excel export
     */

    public function bill_item_detail_report_export() {

        $date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $excelDateRange = $startdate . ' ' . $enddate;

        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if ($userRole != 'admin') {
            if (!empty($cashier_id)) {
                $storeFilter = " AND t.store_id=$cashier_id";
            } elseif (!empty($userLocationId)) {
                $storeFilter = " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = '';
            }
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $storeName = '';
        if (!empty($cashier_id)) {
            $storeData = $this->Location->find('first', [
                'conditions' => ['Location.id' => $cashier_id],
                'fields' => ['Location.name']
            ]);
            $storeName = $storeData['Location']['name'] ?? '';
        } else {
            $storeName = 'All Stores';
        }

        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $taxesDistinct = $this->Order_tax->query("
            SELECT DISTINCT tax_name, tax_percentage
            FROM order_tax ot
            INNER JOIN order_orderhistories h ON h.reference_id = ot.reference_id
            INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
            WHERE h.status = 2
            AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
            AND ot.status = 2
            $storeFilter
        ");
        $taxColumns = [];
        foreach ($taxesDistinct as $td) {
            $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
            $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
            if ($name !== '') {
                $taxColumns[] = $name . "(" . $perc . "%)";
            }
        }
        sort($taxColumns);

        $rows = $this->Order_orderhistory->query("
            SELECT 
                COALESCE(NULLIF(TRIM(loc.print_line3), ''), 'NA') AS state,
                loc.name AS deployment,
                t.orderno AS bill_no,
                t.reference_id AS order_id,
                t.tokenno AS day_serial,
                DATE(t.created) AS bill_date,
                '' AS tab_name,
                h.table_number AS table_no,
                (SELECT MIN(created) FROM order_orderhistories ho WHERE ho.reference_id = t.reference_id AND ho.status IN (1,2)) AS open_time,
                COALESCE(pay.settled_time, t.created) AS close_time,
                h.category_name AS category,
                h.product_name AS item_name,
                h.product_id AS item_number,
                (SELECT name FROM pos_printers WHERE id = h.kds) AS item_section,
                CASE 
                    WHEN cp.food_type = 0 THEN 'Veg'
                    WHEN cp.food_type = 1 THEN 'Non Veg'
                    WHEN cp.food_type = 2 THEN 'Egg'
                    ELSE 'NA'
                END AS item_classification,
                ROUND(h.price, 2) AS rate,
                h.quantity AS qty,
                ROUND(h.price * h.quantity, 2) AS amount,
                ROUND(h.discount, 2) AS discount_amount,
                CASE WHEN h.price * h.quantity > 0 THEN ROUND((h.discount / (h.price * h.quantity)) * 100, 2) ELSE 0 END AS discount_percent,
                ROUND(COALESCE(tax.taxable_price, 0), 2) AS taxable_amount,
                ROUND(COALESCE(tax.total_tax_value, 0), 2) AS gst_total,
                ROUND(COALESCE(tax.sgst_amount, 0), 2) AS sgst_amount,
                ROUND(COALESCE(tax.cgst_amount, 0), 2) AS cgst_amount,
                COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0) AS service_charge_per_item,
                0 AS service_charge_tax,
                ROUND(
                    (h.price * h.quantity) - h.discount
                    + COALESCE(tax.total_tax_value, 0)
                    + COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0),
                    2
                ) AS net_amount,
                'POS' AS source,
                COALESCE(taxmap.tax_map, '') AS tax_map
            FROM order_orderhistories h
            INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
            LEFT JOIN locations loc ON loc.id = t.store_id
            LEFT JOIN catalog_product cp ON cp.id = h.product_id
            LEFT JOIN (
                SELECT 
                    reference_id,
                    product_id,
                    MAX(taxable_price) AS taxable_price,
                    SUM(tax_value) AS total_tax_value,
                    SUM(CASE WHEN tax_name LIKE 'SGST%' THEN tax_value ELSE 0 END) AS sgst_amount,
                    SUM(CASE WHEN tax_name LIKE 'CGST%' THEN tax_value ELSE 0 END) AS cgst_amount
                FROM order_tax
                WHERE status != 0
                GROUP BY reference_id, product_id
            ) tax ON tax.reference_id = h.reference_id AND tax.product_id = h.product_id
            LEFT JOIN (
                SELECT 
                    reference_id,
                    MIN(created) AS settled_time
                FROM order_payments
                WHERE status = 2
                GROUP BY reference_id
            ) pay ON pay.reference_id = h.reference_id
            LEFT JOIN (
                SELECT reference_id, COUNT(*) AS item_count
                FROM order_orderhistories
                WHERE status = 2
                GROUP BY reference_id
            ) ic ON ic.reference_id = h.reference_id
            LEFT JOIN (
                SELECT reference_id, product_id, GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                FROM order_tax
                WHERE status = 2
                AND created BETWEEN '$startDatetime' AND '$endDatetime'
                GROUP BY reference_id, product_id
            ) taxmap ON taxmap.reference_id = h.reference_id AND taxmap.product_id = h.product_id
            WHERE h.status = 2
            AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
            $storeFilter
            ORDER BY t.created ASC, t.orderno ASC, h.id ASC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Bill Item Detail Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Bill_Item_Detail_Report');

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'Bill Item Detail Report (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $baseHeaders = array(
            'State', 'Deployment', 'Bill Number', 'Order Id', 'Day Serial', 'Date',
            'Tab', 'Table No', 'Open Time', 'Close Time', 'Category', 'Item Name',
            'Item Number', 'Item Section', 'Item Classification', 'Rate', 'Qty',
            'Amount', 'Discount Amount', 'Discount %', 'Taxable Amount', 'Net Amount', 'Source'
        );

        $headers = array_merge($baseHeaders, $taxColumns);
        $sheet->fromArray($headers, null, 'A5');

        // Initialize totals for numeric columns
        $totals = [
            'amount'          => 0.0,
            'discount_amount' => 0.0,
            'taxable_amount'  => 0.0,
            'net_amount'      => 0.0,
        ];
        $taxTotals = array_fill_keys($taxColumns, 0.0);

        $startDataRow = 6;
        $rowNum = $startDataRow;
        foreach ($rows as $r) {
            $row = $r[0];
            $loc = $r['loc'];
            $t = $r['t'];
            $h = $r['h'];

            $col = 0;
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['state']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $loc['deployment']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $t['bill_no']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $t['order_id']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $t['day_serial']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['bill_date']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $r['tab_name']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['table_no']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, !empty($row['open_time']) ? date('H:i:s', strtotime($row['open_time'])) : '-');
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, !empty($row['close_time']) ? date('H:i:s', strtotime($row['close_time'])) : '-');
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $h['category']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $h['item_name']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $h['item_number']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['item_section']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['item_classification']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['rate'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $h['qty']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['amount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['discount_amount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['discount_percent'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['taxable_amount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['net_amount'], 2));
            $sheet->setCellValueExplicitByColumnAndRow($col++, $rowNum, $row['source'], PHPExcel_Cell_DataType::TYPE_STRING);

            // Accumulate base totals
            $totals['amount']          += (float)$row['amount'];
            $totals['discount_amount'] += (float)$row['discount_amount'];
            $totals['taxable_amount']  += (float)$row['taxable_amount'];
            $totals['net_amount']      += (float)$row['net_amount'];

            // Build dynamic tax values per row
            $taxValues = array_fill_keys($taxColumns, 0.00);
            $tax_map = $row['tax_map'] ?? '';
            if ($tax_map !== '') {
                $pieces = explode('||', $tax_map);
                foreach ($pieces as $pc) {
                    if (trim($pc) === '') {
                        continue;
                    }
                    $parts = explode('|', $pc);
                    if (count($parts) >= 3) {
                        $tname = $parts[0];
                        $tperc = $parts[1];
                        $tval  = (float)$parts[2];
                        $key = $tname . "(" . $tperc . "%)";
                        if (array_key_exists($key, $taxValues)) {
                            $taxValues[$key] += round($tval, 2);
                        }
                    }
                }
            }

            // Write tax columns and accumulate totals
            foreach ($taxColumns as $tc) {
                $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($taxValues[$tc], 2));
                $taxTotals[$tc] += (float)$taxValues[$tc];
            }

            $rowNum++;
        }

        // Header styling and autosize
        $lastHeaderColumn = $sheet->getCellByColumnAndRow($col - 1, 5)->getColumn();
        $sheet->getStyle('A5:' . $lastHeaderColumn . '5')->getFont()->setBold(true);
        foreach (range('A', $lastHeaderColumn) as $colLetter) {
            $sheet->getColumnDimension($colLetter)->setAutoSize(true);
        }

        // Append grand total row if there is data
        if (!empty($rows)) {
            $totalRow = $rowNum + 1;
            $col = 0;
            // First 17 columns are descriptive (State .. Qty), align "Grand Totals" under the first numeric block
            $sheet->setCellValueByColumnAndRow($col, $totalRow, 'Grand Totals');
            // Merge from first cell through the column before Amount (index 0..16)
            $sheet->mergeCellsByColumnAndRow($col, $totalRow, 16, $totalRow);
            $col = 17; // Amount column index

            // Amount
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, number_format($totals['amount'], 2));
            // Discount Amount
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, number_format($totals['discount_amount'], 2));
            // Discount % (leave blank)
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, '');
            // Taxable Amount
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, number_format($totals['taxable_amount'], 2));
            // Net Amount
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, number_format($totals['net_amount'], 2));
            // Source (blank)
            $sheet->setCellValueByColumnAndRow($col++, $totalRow, '');

            // Dynamic tax grand totals
            foreach ($taxColumns as $tc) {
                $sheet->setCellValueByColumnAndRow($col++, $totalRow, number_format($taxTotals[$tc], 2));
            }

            // Style the grand total row
            $sheet->getStyle('A' . $totalRow . ':' . $sheet->getCellByColumnAndRow($col - 1, $totalRow)->getColumn() . $totalRow)
                ->getFont()->setBold(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Bill_Item_Detail_Report(' . $startdate . '--' . $enddate . ').xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }



    /**
     * Bill Item Detail Report - PDF export
     */
    public function bill_item_detail_report_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'] ?? (date('m/d/Y') . ' - ' . date('m/d/Y'));
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                if (!empty($cashier_id)) {
                    $storeFilter = " AND t.store_id=$cashier_id";
                } elseif (!empty($userLocationId)) {
                    $storeFilter = " AND t.store_id IN (" . $userLocationId . ")";
                } else {
                    $storeFilter = '';
                }
            } else {
                $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }

            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            // Build dynamic tax columns similar to Excel export
            $taxesDistinct = $this->Order_tax->query("
                SELECT DISTINCT tax_name, tax_percentage
                FROM order_tax ot
                INNER JOIN order_orderhistories h ON h.reference_id = ot.reference_id
                INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
                WHERE h.status = 2
                AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
                AND ot.status = 2
                $storeFilter
            ");
            $taxColumns = [];
            foreach ($taxesDistinct as $td) {
                $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
                $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
                if ($name !== '') {
                    $taxColumns[] = $name . "(" . $perc . "%)";
                }
            }
            sort($taxColumns);

            $rows = $this->Order_orderhistory->query("
                SELECT 
                    COALESCE(NULLIF(TRIM(loc.print_line3), ''), 'NA') AS state,
                    loc.name AS deployment,
                    t.orderno AS bill_no,
                    t.reference_id AS order_id,
                    t.tokenno AS day_serial,
                    DATE(t.created) AS bill_date,
                    '' AS tab_name,
                    h.table_number AS table_no,
                    (SELECT MIN(created) FROM order_orderhistories ho WHERE ho.reference_id = t.reference_id AND ho.status IN (1,2)) AS open_time,
                    COALESCE(pay.settled_time, t.created) AS close_time,
                    h.category_name AS category,
                    h.product_name AS item_name,
                    h.product_id AS item_number,
                    (SELECT name FROM pos_printers WHERE id = h.kds) AS item_section,
                    CASE 
                        WHEN cp.food_type = 0 THEN 'Veg'
                        WHEN cp.food_type = 1 THEN 'Non Veg'
                        WHEN cp.food_type = 2 THEN 'Egg'
                        ELSE 'NA'
                    END AS item_classification,
                    ROUND(h.price, 2) AS rate,
                    h.quantity AS qty,
                    ROUND(h.price * h.quantity, 2) AS amount,
                    ROUND(h.discount, 2) AS discount_amount,
                    CASE WHEN h.price * h.quantity > 0 THEN ROUND((h.discount / (h.price * h.quantity)) * 100, 2) ELSE 0 END AS discount_percent,
                    ROUND(COALESCE(tax.taxable_price, 0), 2) AS taxable_amount,
                    ROUND(COALESCE(tax.total_tax_value, 0), 2) AS gst_total,
                    ROUND(COALESCE(tax.sgst_amount, 0), 2) AS sgst_amount,
                    ROUND(COALESCE(tax.cgst_amount, 0), 2) AS cgst_amount,
                    COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0) AS service_charge_per_item,
                    0 AS service_charge_tax,
                    ROUND(
                        (h.price * h.quantity) - h.discount
                        + COALESCE(tax.total_tax_value, 0)
                        + COALESCE(ROUND(COALESCE(t.servicecharge, 0) / NULLIF(ic.item_count, 0), 2), 0),
                        2
                    ) AS net_amount,
                    'POS' AS source,
                    COALESCE(taxmap.tax_map, '') AS tax_map
                FROM order_orderhistories h
                INNER JOIN order_transactions t ON t.reference_id = h.reference_id AND t.status = 2
                LEFT JOIN locations loc ON loc.id = t.store_id
                LEFT JOIN catalog_product cp ON cp.id = h.product_id
                LEFT JOIN (
                    SELECT 
                        reference_id,
                        product_id,
                        MAX(taxable_price) AS taxable_price,
                        SUM(tax_value) AS total_tax_value,
                        SUM(CASE WHEN tax_name LIKE 'SGST%' THEN tax_value ELSE 0 END) AS sgst_amount,
                        SUM(CASE WHEN tax_name LIKE 'CGST%' THEN tax_value ELSE 0 END) AS cgst_amount
                    FROM order_tax
                    WHERE status != 0
                    GROUP BY reference_id, product_id
                ) tax ON tax.reference_id = h.reference_id AND tax.product_id = h.product_id
                LEFT JOIN (
                    SELECT 
                        reference_id,
                        MIN(created) AS settled_time
                    FROM order_payments
                    WHERE status = 2
                    GROUP BY reference_id
                ) pay ON pay.reference_id = h.reference_id
                LEFT JOIN (
                    SELECT reference_id, COUNT(*) AS item_count
                    FROM order_orderhistories
                    WHERE status = 2
                    GROUP BY reference_id
                ) ic ON ic.reference_id = h.reference_id
                LEFT JOIN (
                    SELECT reference_id, product_id, GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                    FROM order_tax
                    WHERE status = 2
                    AND created BETWEEN '$startDatetime' AND '$endDatetime'
                    GROUP BY reference_id, product_id
                ) taxmap ON taxmap.reference_id = h.reference_id AND taxmap.product_id = h.product_id
                WHERE h.status = 2
                AND h.created BETWEEN '$startDatetime' AND '$endDatetime'
                $storeFilter
                ORDER BY t.created ASC, t.orderno ASC, h.id ASC
            ");

            $this->set(compact('startdate', 'enddate', 'store_name', 'rows', 'taxColumns'));
            $this->render('bill_item_detail_report_pdf');
        }
    }

    /**
    * Bill Wise Sales Report - Main view
    */
    public function bill_wise_sales_report() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";

        $startDate = date('m/d/Y');
        $endDate = date('m/d/Y');
        $yourStartDateValue = $startDate . ' - ' . $endDate;
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate = date('Y-m-d', strtotime($endDate));

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $conditions = [
            'status' => 1,
            'type'   => 'Outlet'
        ];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $userLocationIds = Hash::extract(
                ['ids' => is_array($userLocationId) ? $userLocationId : explode(',', $userLocationId)],
                'ids.{n}'
            );
            $conditions['id IN'] = array_map('trim', $userLocationIds);
        }
        $users = $this->Location->find('all', ['conditions' => $conditions]);

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $endDate = date('m/d/Y', strtotime($end_date));
            $yourStartDateValue = $startDate . ' - ' . $endDate;
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));
            $cashier_id = $this->request->data['Search']['cashier'] ?? '';
        } else {
            $cashier_id = '';
        }

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id
                ? " AND t.store_id=$cashier_id"
                : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }
        
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Build dynamic tax columns
        $taxesDistinct = $this->Order_tax->query("
            SELECT DISTINCT tax_name, tax_percentage
            FROM order_tax ot
            INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
            WHERE t.status = 2
            AND DATE(t.created) BETWEEN '$startDatetime' AND '$endDatetime'
            AND ot.status = 2
            $storeFilter
        ");
        $taxColumns = [];
        foreach ($taxesDistinct as $td) {
            $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
            $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
            if ($name !== '') {
                $taxColumns[] = $name . "(" . $perc . "%)";
            }
        }
        sort($taxColumns);


        $rows = $this->Order_transaction->query("
            SELECT 
                t.orderno AS bill_number,
                t.reference_id AS order_id,
                DATE(t.created) AS bill_date,
                TIME(t.created) AS bill_time,
                t.created AS print_time,
                COALESCE(
                    (SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2),
                    t.created
                ) AS close_time,
                COALESCE(t.table_number, '') AS table_number,
                COALESCE(t.pax, 0) AS covers,
                ROUND(COALESCE(
                    (SELECT SUM(h.price * h.quantity) 
                    FROM order_orderhistories h 
                    WHERE h.reference_id = t.reference_id 
                    AND h.status = 2), 0), 2) AS total,
                ROUND(t.discount, 2) AS discount,
                ROUND(COALESCE(
                    (SELECT SUM(h.price * h.quantity) 
                    FROM order_orderhistories h 
                    WHERE h.reference_id = t.reference_id 
                    AND h.status = 2), 0) - t.discount, 2) AS net_total,
                ROUND(t.amount, 2) AS gross_bill_amount,
                ROUND(COALESCE(t.servicecharge, 0), 2) AS total_service_charge,
                COALESCE(taxmap.tax_map, '') AS tax_map
            FROM order_transactions t
            LEFT JOIN (
                SELECT 
                    reference_id,
                    GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                FROM order_tax
                WHERE status = 2
                AND created BETWEEN '$startDatetime' AND '$endDatetime'
                GROUP BY reference_id
            ) taxmap ON taxmap.reference_id = t.reference_id
            WHERE t.status = 2
            AND t.created BETWEEN '$startDatetime' AND '$endDatetime'
            $storeFilter
            ORDER BY t.created ASC
        ");

        $this->set(compact('users', 'yourStartDateValue', 'rows', 'cashier_id', 'taxColumns'));
    }


    /**
     * Bill Wise Sales Report - Excel export
     */
    public function bill_wise_sales_report_export() {

        $date_range = $_GET['sdate'];
        $dates = explode(" - ", $date_range);
        $start_date = trim($dates[0]);
        $end_date = trim($dates[1]);
        $startdate = date('Y-m-d', strtotime($start_date));
        $enddate = date('Y-m-d', strtotime($end_date));
        $excelDateRange = $startdate . ' ' . $enddate;

        $cashier_id = $_GET['cashier'] ?? '';

        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        if ($userRole != 'admin') {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : " AND t.store_id IN (" . $userLocationId . ")";
        } else {
            $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
        }

        $storeName = '';
        if ($cashier_id) {
            $storeData = $this->Order_transaction->query("SELECT name FROM locations WHERE id = $cashier_id LIMIT 1");
            $storeName = $storeData ? $storeData[0]['locations']['name'] : '';
        } else {
            $storeName = 'All Stores';
        }
        
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // Build dynamic tax columns for export
        $taxesDistinct = $this->Order_tax->query("
            SELECT DISTINCT tax_name, tax_percentage
            FROM order_tax ot
            INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
            WHERE t.status = 2
            AND DATE(t.created) BETWEEN '$startDatetime' AND '$endDatetime'
            AND ot.status = 2
            $storeFilter
        ");
        $taxColumns = [];
        foreach ($taxesDistinct as $td) {
            $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
            $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
            if ($name !== '') {
                $taxColumns[] = $name . "(" . $perc . "%)";
            }
        }
        sort($taxColumns);

        $rows = $this->Order_transaction->query("
            SELECT 
                t.orderno AS bill_number,
                t.reference_id AS order_id,
                DATE(t.created) AS bill_date,
                TIME(t.created) AS bill_time,
                t.created AS print_time,
                COALESCE(
                    (SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2),
                    t.created
                ) AS close_time,
                COALESCE(t.table_number, '') AS table_number,
                COALESCE(t.pax, 0) AS covers,
                ROUND(COALESCE(
                    (SELECT SUM(h.price * h.quantity) 
                    FROM order_orderhistories h 
                    WHERE h.reference_id = t.reference_id 
                    AND h.status = 2), 0), 2) AS total,
                ROUND(t.discount, 2) AS discount,
                ROUND(COALESCE(
                    (SELECT SUM(h.price * h.quantity) 
                    FROM order_orderhistories h 
                    WHERE h.reference_id = t.reference_id 
                    AND h.status = 2), 0) - t.discount, 2) AS net_total,
                ROUND(t.amount, 2) AS gross_bill_amount,
                ROUND(COALESCE(t.servicecharge, 0), 2) AS total_service_charge,
                COALESCE(taxmap.tax_map, '') AS tax_map
            FROM order_transactions t
            LEFT JOIN (
                SELECT 
                    reference_id,
                    GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                FROM order_tax
                WHERE status = 2
                AND created BETWEEN '$startDatetime' AND '$endDatetime'
                GROUP BY reference_id
            ) taxmap ON taxmap.reference_id = t.reference_id
            WHERE t.status = 2
            AND t.created BETWEEN '$startDatetime' AND '$endDatetime'
            $storeFilter
            ORDER BY t.created ASC
        ");

        App::import('Vendor', 'PHPExcel/PHPExcel');
        $objPHPExcel = new PHPExcel();
        $objPHPExcel->getProperties()->setCreator("Aether")->setTitle("Bill Wise Sales Report");
        $sheet = $objPHPExcel->getActiveSheet();
        $sheet->setTitle('Bill_Wise_Sales');

        $sheet->setCellValue('A1', $storeName);
        $sheet->setCellValue('A2', 'Bill Wise Sales Report (' . $excelDateRange . ')');
        $sheet->setCellValue('A3', 'Generated On: ' . date('Y-m-d H:i:s'));

        $baseHeaders = array(
            'Bill Number', 'Order ID', 'Bill Date', 'Bill Time', 'Print Time', 'Close Time',
            'Table Number', 'Covers', 'Total', 'Discount', 'Net Total', 'Gross Bill Amount', 'Total Service Charge'
        );
        $headers = array_merge($baseHeaders, $taxColumns);
        $sheet->fromArray($headers, null, 'A5');

        $rowNum = 6;

        // Grand totals for numeric columns
        $grandTotals = [
            'covers' => 0,
            'total' => 0,
            'discount' => 0,
            'net_total' => 0,
            'gross_bill_amount' => 0,
            'total_service_charge' => 0,
        ];
        $taxTotals = array_fill_keys($taxColumns, 0.0);

        foreach ($rows as $r) {
            $row = $r[0];
            $t = $r['t'];

            $grandTotals['covers'] += (float)$row['covers'];
            $grandTotals['total'] += (float)$row['total'];
            $grandTotals['discount'] += (float)$row['discount'];
            $grandTotals['net_total'] += (float)$row['net_total'];
            $grandTotals['gross_bill_amount'] += (float)$row['gross_bill_amount'];
            $grandTotals['total_service_charge'] += (float)$row['total_service_charge'];

            $col = 0;
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $t['bill_number']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $t['order_id']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['bill_date']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['bill_time']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, date('H:i:s', strtotime($row['print_time'])));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, date('H:i:s', strtotime($row['close_time'])));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['table_number']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $row['covers']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['total'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['discount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['net_total'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['gross_bill_amount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($row['total_service_charge'], 2));

            // Dynamic tax per bill
            $rowTaxValues = array_fill_keys($taxColumns, 0.0);
            $tax_map = isset($row['tax_map']) ? $row['tax_map'] : '';
            if (!empty($tax_map)) {
                $pieces = explode('||', $tax_map);
                foreach ($pieces as $pc) {
                    if (trim($pc) === '') {
                        continue;
                    }
                    $parts = explode('|', $pc);
                    if (count($parts) >= 3) {
                        $tname = $parts[0];
                        $tperc = $parts[1];
                        $tval  = (float)$parts[2];
                        $key   = $tname . "(" . $tperc . "%)";
                        if (array_key_exists($key, $rowTaxValues)) {
                            $rowTaxValues[$key] += round($tval, 2);
                        }
                    }
                }
            }

            foreach ($taxColumns as $tc) {
                $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($rowTaxValues[$tc], 2));
                $taxTotals[$tc] += $rowTaxValues[$tc];
            }

            $rowNum++;
        }

        // Grand total row
        if (!empty($rows)) {
            $sheet->setCellValue("A$rowNum", "Grand Total");
            $sheet->mergeCells("A$rowNum:G$rowNum");

            $col = 7; // Covers column index
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, $grandTotals['covers']);
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($grandTotals['total'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($grandTotals['discount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($grandTotals['net_total'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($grandTotals['gross_bill_amount'], 2));
            $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($grandTotals['total_service_charge'], 2));

            foreach ($taxColumns as $tc) {
                $sheet->setCellValueByColumnAndRow($col++, $rowNum, number_format($taxTotals[$tc], 2));
            }

            $lastColLetter = $sheet->getCellByColumnAndRow($col - 1, $rowNum)->getColumn();
            $grandTotalStyle = $sheet->getStyle("A$rowNum:" . $lastColLetter . $rowNum);
            $grandTotalStyle->getFont()->setBold(true);
            $grandTotalStyle->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
            $grandTotalStyle->getFill()->getStartColor()->setRGB('E0E0E0');
        }

        // Header style & autosize
        $lastHeaderColLetter = $sheet->getCellByColumnAndRow(count($headers) - 1, 5)->getColumn();
        $sheet->getStyle('A5:' . $lastHeaderColLetter . '5')->getFont()->setBold(true);
        foreach (range('A', $lastHeaderColLetter) as $colLetter) {
            $sheet->getColumnDimension($colLetter)->setAutoSize(true);
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="Bill_Wise_Sales_Report(' . $startdate . '--' . $enddate . ').xls"');
        header('Cache-Control: max-age=0');
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
        $writer->save('php://output');
        exit;
    }



    /**
     * Bill Wise Sales Report - PDF export
     */
    public function bill_wise_sales_report_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "login";

        if ($this->request->is(['post', 'put'])) {
            $date_range = $this->request->data['sdate'];
            $dates = explode(" - ", $date_range);
            $start_date = trim($dates[0]);
            $end_date = trim($dates[1]);
            $startdate = date('Y-m-d', strtotime($start_date));
            $enddate = date('Y-m-d', strtotime($end_date));

            $cashier_id = $this->request->data['cashier'] ?? '';

            $authUser = $this->Session->read('Auth.User');
            $userRole = $authUser['role'] ?? '';
            $userLocationId = $authUser['location_ids'] ?? 0;

            if ($userRole != 'admin') {
                $storeFilter = $cashier_id
                    ? " AND t.store_id=$cashier_id"
                    : " AND t.store_id IN (" . $userLocationId . ")";
            } else {
                $storeFilter = $cashier_id ? " AND t.store_id=$cashier_id" : '';
            }

            if (!empty($cashier_id)) {
                $store = $this->Location->find('first', [
                    'conditions' => ['Location.id' => $cashier_id],
                    'fields' => ['Location.name']
                ]);
                $store_name = $store['Location']['name'] ?? '';
            } else {
                $store_name = 'All Stores';
            }
            
            
            $startDatetime = $startdate . ' ' . shiftstart;
            $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

            // Build dynamic tax columns for PDF
            $taxesDistinct = $this->Order_tax->query("
                SELECT DISTINCT tax_name, tax_percentage
                FROM order_tax ot
                INNER JOIN order_transactions t ON t.reference_id = ot.reference_id
                WHERE t.status = 2
                AND DATE(t.created) BETWEEN '$startDatetime' AND '$endDatetime'
                AND ot.status = 2
                $storeFilter
            ");
            $taxColumns = [];
            foreach ($taxesDistinct as $td) {
                $name = $td['ot']['tax_name'] ?? $td[0]['tax_name'] ?? '';
                $perc = $td['ot']['tax_percentage'] ?? $td[0]['tax_percentage'] ?? '';
                if ($name !== '') {
                    $taxColumns[] = $name . "(" . $perc . "%)";
                }
            }
            sort($taxColumns);

            $rows = $this->Order_transaction->query("
                SELECT 
                    t.orderno AS bill_number,
                    t.reference_id AS order_id,
                    DATE(t.created) AS bill_date,
                    TIME(t.created) AS bill_time,
                    t.created AS print_time,
                    COALESCE(
                        (SELECT MIN(created) FROM order_payments p WHERE p.reference_id = t.reference_id AND p.status = 2),
                        t.created
                    ) AS close_time,
                    COALESCE(t.table_number, '') AS table_number,
                    COALESCE(t.pax, 0) AS covers,
                    ROUND(COALESCE(
                        (SELECT SUM(h.price * h.quantity) 
                        FROM order_orderhistories h 
                        WHERE h.reference_id = t.reference_id 
                        AND h.status = 2), 0), 2) AS total,
                    ROUND(t.discount, 2) AS discount,
                    ROUND(COALESCE(
                        (SELECT SUM(h.price * h.quantity) 
                        FROM order_orderhistories h 
                        WHERE h.reference_id = t.reference_id 
                        AND h.status = 2), 0) - t.discount, 2) AS net_total,
                    ROUND(t.amount, 2) AS gross_bill_amount,
                    ROUND(COALESCE(t.servicecharge, 0), 2) AS total_service_charge,
                    COALESCE(taxmap.tax_map, '') AS tax_map
                FROM order_transactions t
                LEFT JOIN (
                    SELECT 
                        reference_id,
                        GROUP_CONCAT(CONCAT(tax_name, '|', tax_percentage, '|', ROUND(tax_value,2)) SEPARATOR '||') AS tax_map
                    FROM order_tax
                    WHERE status = 2
                    AND created BETWEEN '$startDatetime' AND '$endDatetime'
                    GROUP BY reference_id
                ) taxmap ON taxmap.reference_id = t.reference_id
                WHERE t.status = 2
                AND t.created BETWEEN '$startDatetime' AND '$endDatetime'
                $storeFilter
                ORDER BY t.created ASC
            ");

            $datas = [];
            foreach ($rows as $r) {
                $row = $r[0];
                $t = $r['t'];
                $datas[] = [
                    'bill_number' => $t['bill_number'],
                    'order_id' => $t['order_id'],
                    'bill_date' => $row['bill_date'],
                    'bill_time' => $row['bill_time'],
                    'print_time' => $row['print_time'],
                    'close_time' => $row['close_time'],
                    'table_number' => $row['table_number'],
                    'covers' => $row['covers'],
                    'total' => $row['total'],
                    'discount' => $row['discount'],
                    'net_total' => $row['net_total'],
                    'gross_bill_amount' => $row['gross_bill_amount'],
                    'total_service_charge' => $row['total_service_charge'],
                    'tax_map' => $row['tax_map'],
                ];
            }

            $this->set(compact('startdate', 'enddate', 'datas', 'store_name', 'taxColumns'));
            $this->render('bill_wise_sales_report_pdf');
        }
    }
    
    public function create_offers() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $this->layout = "users";
    
        $startDate = date("Y-m-d");
        $startTime = date("H:i");
        
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? '';
        
        
        // Add 1 hour to current time
        $endTimestamp = strtotime("+1 hour");
        $endDate = date("Y-m-d", $endTimestamp);
        $endTime = date("H:i", $endTimestamp);
        
        // Send all values to view
        $this->set(compact(
            'startDate',
            'startTime',
            'endDate',
            'endTime'
        ));
        // Load categories and subcategories into grouped select options
        $categorys = $this->Catalog_category->find('all', ['conditions' => ['status' => 1]]);
        $options = [];
    
        foreach ($categorys as $category) {
            $cat_id = $category['Catalog_category']['id'];
            $cat_name = $category['Catalog_category']['name'];
    
            $subcategorys = $this->Catalog_subcategory->find('all', [
                'conditions' => ['cat_id' => $cat_id, 'status' => 1]
            ]);
    
            if ($subcategorys) {
                $options[$cat_name] = [];
                foreach ($subcategorys as $sub) {
                    // $options[$cat_name][$sub['Catalog_subcategory']['id']] = $sub['Catalog_subcategory']['name'];
                    $sub_id = $sub['Catalog_subcategory']['id'];
                    $sub_name = $sub['Catalog_subcategory']['name'];
                    $options[$cat_name]["sub_$sub_id"] = $sub_name;
                }
            } else {
                $options["cat_$cat_id"] = $cat_name;
            }
        }
        $this->set(compact('options'));

        $user="SELECT * FROM `catalog_product`  where status=1 order by catalog_product.name ASC"; 
        $users=$this->Catalog_product->query($user);
        $this->set(compact('users'));
        $this->set(compact('id'));
        
        $conditions = ['status' => 1];
        
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $ids = array_filter(array_map('trim', explode(',', $userLocationId))); // clean IDs
            if (!empty($ids)) {
                $conditions['id IN'] = $ids;
            }
        }
        
        $locations=$this->Location->find('all',['conditions' => $conditions]);
        $this->set(compact('locations'));
        
        
        if ($this->request->is('post')) {
    
            // ----------------------------
            // 1️⃣ Collect Basic Offer Data
            // ----------------------------
            $offer_name = $this->request->data('offer_name');
            $offer_type = $this->request->data('offer_type');
            $apply_type = $this->request->data('type');   // item / category
            
            $start_date = $this->request->data('start_date');
            $start_time = $this->request->data('start_time');
            $end_date   = $this->request->data('end_date');
            $end_time   = $this->request->data('end_time');
            $location   = $this->request->data('location');
            // Normalize to array
            if (!is_array($location)) {
                $location = [$location];
            }
            
            $offer_start = $start_date . " " . $start_time;
            $offer_end   = $end_date   . " " . $end_time;
            
            $checkedData = json_decode($this->request->data('checkedData'), true);
            $categoryInput = $this->request->data('category');
            
            $itemsToSave = [];
            $category_id = null;
            $category_name = null;
            $subcategory_id = null;
            $subcategory_name = null;
            
            
            // ===========================================================
            // CASE 1️⃣ : CATEGORY WISE
            // ===========================================================
            if ($apply_type == 'category') {
            
                // If category selected
                if (strpos($categoryInput, 'cat_') === 0) {
            
                    $category_id = (int) str_replace('cat_', '', $categoryInput);
            
                    $cat = $this->Catalog_category->findById($category_id);
                    if ($cat) {
                        $category_name = $cat['Catalog_category']['name'];
                    }
            
                    $products = $this->Catalog_product->find('all', [
                        'conditions' => ['cat_id' => $category_id, 'status' => 1]
                    ]);
            
                    foreach ($products as $p) {
                        $itemsToSave[] = [
                            'sku_id'      => $p['Catalog_product']['id'],
                            'sku_name'    => $p['Catalog_product']['name'],
                            'cat_id'      => $category_id,
                            'cat_name'    => $category_name,
                            'subcat_id'   => null,
                            'subcat_name' => null
                        ];
                    }
                }
            
                // If subcategory selected
                elseif (strpos($categoryInput, 'sub_') === 0) {
            
                    $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
            
                    $subcat = $this->Catalog_subcategory->findById($subcategory_id);
            
                    if ($subcat) {
                        $subcategory_name = $subcat['Catalog_subcategory']['name'];
                        $category_id      = $subcat['Catalog_subcategory']['cat_id'];
                        $category_name    = $this->Catalog_category->field('name', ['id' => $category_id]);
                    }
            
                    $products = $this->Catalog_product->find('all', [
                        'conditions' => [
                            'cat_id'    => $category_id,
                            'subcat_id' => $subcategory_id,
                            'status'    => 1
                        ]
                    ]);
            
                    foreach ($products as $p) {
                        $itemsToSave[] = [
                            'sku_id'      => $p['Catalog_product']['id'],
                            'sku_name'    => $p['Catalog_product']['name'],
                            'cat_id'      => $category_id,
                            'cat_name'    => $category_name,
                            'subcat_id'   => $subcategory_id,
                            'subcat_name' => $subcategory_name
                        ];
                    }
                }
            }
            
            
            
            // ===========================================================
            // CASE 2️⃣ : ITEM WISE (SAVE CAT + SUBCAT ALSO)
            // ===========================================================
            elseif ($apply_type == 'item') {
            
                foreach ($checkedData as $i) {
                    $itemsToSave[] = [
                        'sku_id'        => $i['id'],
                        'sku_name'      => $i['sku_name'],
                        'cat_id'        => $i['cat_id'],       // SAVE CATEGORY ALSO
                        'cat_name'      => $i['cat_name'],
                        'subcat_id'     => $i['subcat_id'],
                        'subcat_name'   => $i['subcat_name']
                    ];
                }
            }
            
            
            // Generate unique stockin_id
            do {
                $txnid = rand(1, 9);
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
    
                $existing = $this->Offer->find('first', [
                    'conditions' => ['offer_id' => $txnid]
                ]);
            } while ($existing);
            
            if($itemsToSave){
                // ===========================================================
                // SAVE INTO TABLE (MULTIPLE ROWS)
                // ===========================================================
                foreach ($itemsToSave as $product) {
                
                    foreach ($location as $locId) {
                        
                        $locationdetail = $this->Location->find('first', array(
                            'conditions' => array('Location.id' => $locId)
                        ));
                    
                        if (!empty($locationdetail)) {
                            $location_name = $locationdetail['Location']['name'];
                        }
                        
                        $saveData = [
                            'Offer' => [
                                'offer_id'     => $txnid,
                                
                                'name'         => $offer_name,
                                'offer_type'   => $offer_type,
                                'item_type'    => $apply_type,
                                
                                'location_id'  => $locId,   // 👈 SAVE HERE
                                'location_name'=> $location_name,   // 👈 SAVE HERE
        
                                // CATEGORY + SUBCATEGORY NOW SAVED IN ALL CASES
                                'cat_id'       => $product['cat_id'],
                                'cat_name'     => $product['cat_name'],
                                'subcat_id'    => $product['subcat_id'],
                                'subcat_name'  => $product['subcat_name'],
                    
                                // ITEM DATA
                                'sku_id'       => $product['sku_id'],
                                'sku_name'     => $product['sku_name'],
                    
                                // PERIOD
                                'start_date'   => $start_date,
                                'start_time'   => $start_time,
                                'end_date'     => $end_date,
                                'end_time'     => $end_time,
                    
                                'status'       => 1,
                                'sync'=>0,
                                'local_sync'=>0
                            ]
                        ];
                    
                        $this->Offer->create();
                        $this->Offer->save($saveData);
                    }
                }
                
                
                // SUCCESS RESPONSE
                echo json_encode([
                    'status' => true,
                    'msg'    => "Offer Saved Successfully"
                ]);
                exit;
            }else{
                echo json_encode([
                    'status' => false,
                    'msg'    => "No Item found"
                ]);
                exit;
            }

        }
    }
    
    public function offers() {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime('-12 months'));
        $endDate = date('m/d/Y');
        
        if($userRole == 'subadmin'){
            $id = $authUser['id'];                      
            $locations = $this->User_location->find('list', [
                'conditions' => ['status' => 1, 'user_id' => $id],
                'fields' => ['location_id']
            ]);
            $userLocationId = implode(',', array_values($locations));
        }
        
        if($this->request->is('post', 'put'))
        {
            $daterange= $this->request->data['daterange'];
            $dates = explode(" - ", $daterange);
            $start_date = trim($dates[0]);
            $startDate = date('m/d/Y', strtotime($start_date));
            $end_date = trim($dates[1]);
            $endDate = date('m/d/Y', strtotime($end_date));
            $startdate= date('Y-m-d', strtotime($start_date));
            $enddate= date('Y-m-d', strtotime($end_date));
        }else{
            $startdate= date('Y-m-d', strtotime($startDate));
            $enddate= date('Y-m-d', strtotime($endDate));
        }   
        
        $locationCondition = '';
        if ($userRole !== 'admin') {
            $locationCondition = "AND location_id IN (" . $userLocationId .")";
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        // $users = $this->Offer->query("SELECT * FROM pos_offers where created between '$startdate 00:00:01' and  '$enddate 23:59:59' $locationCondition group by offer_id ORDER BY id desc");
        $users = $this->Offer->query("
            SELECT 
                offer_id,
                name,
                offer_type,
                start_date,
                end_date,
                start_time,
                end_time,
                created,
                MAX(status) AS offer_status
            FROM pos_offers
            WHERE created BETWEEN '$startDatetime' AND '$endDatetime' and status=1
            $locationCondition
            GROUP BY offer_id
            ORDER BY MAX(id) DESC
        ");
        $yourStartDateValue=$startDate . ' - ' . $endDate;
        $this->set('startdate', $yourStartDateValue);
        
        $this->set(compact('users'));

    }
    
    public function offer_change_status() {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $Id = $this->request->data['_id'];
            
            // Get current status
            $current = $this->Offer->find('first', [
                'conditions' => ['Offer.offer_id' => $Id],
                'fields' => ['Offer.status']
            ]);
            
            if ($current) {
                // $newStatus = ($current['Offer']['status'] == 1) ? 0 : 1;
            
                // Update using updateAll()
                $this->Offer->updateAll(
                    [
                        'Offer.status' => 0,
                        'Offer.sync'       => 0,
                        'Offer.local_sync' => 0
                    ],
                    ['Offer.offer_id' => $Id]
                );

                echo json_encode(['status' => true]);
            }else {
                echo json_encode(['status' => false]);
            }
        }
    }

    public function view_offer()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Offer->query("SELECT 
            offer_id,
            GROUP_CONCAT(DISTINCT location_name ORDER BY location_name SEPARATOR ', ') AS locations,
            MAX(name)        AS name,
            MAX(sku_name)        AS sku_name,
            MAX(cat_name)        AS cat_name,
            MAX(subcat_name)        AS subcat_name,
            MAX(item_type) AS item_type,
            MAX(offer_type) AS offer_type,
            MAX(start_date) AS start_date,
            MAX(end_date)   AS end_date,
            MAX(start_time) AS start_time,
            MAX(end_time)   AS end_time
        FROM pos_offers
        WHERE status = 1
          AND offer_id = '$id'
        GROUP BY offer_id;
        ");
        
        $items = $this->Offer->query("
            SELECT 
                sku_name,
                cat_name,
                subcat_name
            FROM pos_offers
            WHERE status = 1
              AND offer_id = '$id' group by sku_id
            ORDER BY id DESC
        ");
        
        $this->set(compact('indents', 'items'));

    }
    
    public function po_approve_list()
    {
        // Redirect if not authenticated
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = "users";
        $authUser = $this->Session->read('Auth.User');
        $userRole = $authUser['role'] ?? '';
        $locationIds = $authUser['location_ids'] ?? '';

        // --- Default date range (last 1 month)
        $startDate = date('m/d/Y', strtotime('-1 month'));
        $endDate   = date('m/d/Y');
        $startDateFormatted = date('Y-m-d', strtotime('-1 month'));
        $endDateFormatted   = date('Y-m-d');

        // --- Handle custom date range from form
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            if (strpos($daterange, '-') !== false) {
                list($startRaw, $endRaw) = explode(" - ", $daterange);
                $startDate = trim($startRaw);
                $endDate   = trim($endRaw);
                $startDateFormatted = date('Y-m-d', strtotime($startDate));
                $endDateFormatted   = date('Y-m-d', strtotime($endDate));
            }
        }

        // --- Build store conditions
        $conditions2 = ['status' => 1];

        if ($userRole !== 'admin' && !empty($locationIds)) {
            // Normalize location IDs to array
            $userLocationIds = Hash::extract(
                ['ids' => is_array($locationIds) ? $locationIds : explode(',', $locationIds)],
                'ids.{n}'
            );
            $conditions2['id IN'] = array_map('trim', $userLocationIds);
        }

        // --- Fetch stores
        $stores = $this->Location->find('all', [
            'conditions' => $conditions2
        ]);
        
        $startDatetime = $startDateFormatted . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($endDateFormatted . ' +1 day')) . ' ' . shiftend;

        // --- Build purchase order conditions
        $poConditions = [
            "direct_purchase" => 0,
            "created >=" => $startDatetime,
            "created <=" => $endDatetime,
        ];

        if ($userRole !== 'admin' && !empty($conditions2['id IN'])) {
            $poConditions['location_id IN'] = $conditions2['id IN'];
        }

        // --- Apply cashier search (overrides for all roles)
        if (!empty($this->request->data['Search']['cashier'])) {
            $cashierId = (int)$this->request->data['Search']['cashier'];
            $poConditions['location_id'] = $cashierId;
        }

        // --- Fetch purchase orders
        $purchaseOrders = $this->Inventory_purchase_order->find('all', [
            'conditions' => $poConditions,
            'order' => ['id' => 'DESC']
        ]);
        
        
        // $dbo = $this->Inventory_purchase_order->getDataSource();
        // $logs = $dbo->getLog();
        // $lastQuery = end($logs['log']);
        // debug($lastQuery);die;

        // --- Pass data to view
        $this->set(compact('stores', 'purchaseOrders'));
        $this->set('startdate', $startDate . ' - ' . $endDate);
    }
    
    public function view_approve_po()
    {
        if(!$this->Session->check('Auth.User.id')){
            $this->redirect(array('controller'=>'dashboard','action' => 'login'));      
        }
        
        $this->layout = "users";
        $id=$_REQUEST['id'];
    
        $indents = $this->Inventory_purchase_order->query("SELECT * FROM inventory_purchase_order where p_o_id=$id");
        $this->set(compact('indents'));
        
        $items = $this->Inventory_purchase_order_item->query("SELECT * FROM inventory_purchase_order_items where p_o_id=$id and status!=0");
        
        $this->set(compact('items'));
    }
    
    public function update_approve_po() 
    {
        $this->autoRender = false; // Disable view rendering
    
        if ($this->request->is('post')) {
            $poid = $this->request->data['_id'];
            $items = $this->request->data['_items']; // array of item_id and quantity
        
            $today = date('Y-m-d H:i:s');
            $id = $this->Session->read('Auth.User.id');
        
            // Get user name safely
            $user = $this->User->find('first', [
                'conditions' => ['User.id' => $id],
                'fields' => ['User.name'],
                'recursive' => -1
            ]);
            $name = $user['User']['name'];
        
            $amount = 0;
        
            foreach ($items as $item) {
                $itemId = (int)$item['item_id'];
                $quantity = (float)$item['quantity'];
        
                // Fetch SKU ID from PO item
                $poItem = $this->Inventory_purchase_order_item->find('first', [
                    'conditions' => ['Inventory_purchase_order_item.id' => $itemId,'Inventory_purchase_order_item.status' => 1],
                    'fields' => ['Inventory_purchase_order_item.sku_id','sku_price'],
                    'recursive' => -1
                ]);
                $sku_id = $poItem['Inventory_purchase_order_item']['sku_id'];
                $price = $poItem['Inventory_purchase_order_item']['sku_price'];
        
                // Get total tax percentage for SKU
                $taxResult = $this->Inventory_sku_tax->query(
                    "SELECT SUM(tax_percentage) AS total_tax FROM inventory_sku_tax WHERE product_id = '$sku_id' and status=1"
                );
                $total_tax = round($taxResult[0][0]['total_tax'], 2);
        
                // Calculate tax & total amount
                $tax_value = round(($price * $quantity) * ($total_tax / 100), 2);
                $skuamount = round(($price * $quantity) + $tax_value, 2);
        
                // Update purchase order item
                $this->Inventory_purchase_order_item->updateAll(
                    [
                        'Inventory_purchase_order_item.approved_quantity' => $quantity,
                        'Inventory_purchase_order_item.approved_total_tax_value' => $tax_value,
                        'Inventory_purchase_order_item.approved_amount' => $skuamount,
                        'Inventory_purchase_order_item.status' => 2,
                        'Inventory_purchase_order_item.sync' => 0,
                        'Inventory_purchase_order_item.local_sync' => 0
                    ],
                    [
                        'Inventory_purchase_order_item.id' => $itemId,
                        'Inventory_purchase_order_item.p_o_id' => $poid,
                        'Inventory_purchase_order_item.status' => 1
                    ]
                );
        
                $amount += $skuamount;
            }
        
            // Update main purchase order
            $this->Inventory_purchase_order->updateAll(
                [
                    'Inventory_purchase_order.status' => 2,
                    'Inventory_purchase_order.approved_by_id' => $id,
                    'Inventory_purchase_order.approved_by_name' => "'$name'", // string needs quoting
                    'Inventory_purchase_order.approved_on' => "'$today'",      // string needs quoting
                    'Inventory_purchase_order.approved_amount' => $amount,
                    'Inventory_purchase_order.sync' => 0,
                    'Inventory_purchase_order.local_sync' => 0
                ],
                [
                    'Inventory_purchase_order.p_o_id' => $poid,
                    'Inventory_purchase_order.status' => 1
                ]
            );
        
            echo json_encode(['status' => true]);
            exit;
        }

    }
    
    
    public function update_location_publish()
    {
        $this->autoRender = false;
    
        if ($this->request->is('post')) {
    
            $store_id = $this->request->data('store_id');
    
            if (!empty($store_id)) {
                // Publish single store
                $this->Location->updateAll(
                    ['Location.is_publish' => '0'],
                    ['Location.id' => $store_id]
                );
            } else {
                // Publish all stores
                $this->Location->updateAll(
                    ['Location.is_publish' => '0']
                );
            }
    
            echo json_encode([
                'success' => true
            ]);
        }
    }
    
    public function edit_offer()
    {
        /* ===============================
         * AUTH CHECK
         * =============================== */
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
    
        $this->layout = "users";
    
        /* ===============================
         * GET OFFER ID
         * =============================== */
        $offer_id = $this->request->query('id');
        if (empty($offer_id)) {
            return $this->redirect(['action' => 'offers']);
        }
    
        /* ===============================
         * FETCH OFFER ROWS
         * =============================== */
        $offerRows = $this->Offer->find('all', [
            'conditions' => [
                'Offer.offer_id' => $offer_id,
                'Offer.status'   => 1
            ]
        ]);
    
        if (empty($offerRows)) {
            return $this->redirect(['action' => 'offers']);
        }
    
        $offer = $offerRows[0]['Offer'];
    
        /* ===============================
         * SELECTED SKU IDS (FOR CHECKBOX)
         * =============================== */
        $selectedSkuIds = array_unique(
            array_filter(
                Hash::extract($offerRows, '{n}.Offer.sku_id')
            )
        );
        
        $allLocations = $this->Location->find('list', [
            'conditions' => ['Location.status' => 1],
            'order'      => ['Location.name' => 'ASC']
        ]);

        /* ===============================
         * SELECTED LOCATION IDS
         * =============================== */
        $selectedLocationIds = array_unique(
            array_filter(
                Hash::extract($offerRows, '{n}.Offer.location_id')
            )
        );
        
        $locations = [];
        
        // 1️⃣ Add selected locations first
        foreach ($selectedLocationIds as $locId) {
            if (isset($allLocations[$locId])) {
                $locations[$locId] = $allLocations[$locId];
                unset($allLocations[$locId]); // remove from main list
            }
        }
        
        // 2️⃣ Add remaining locations
        foreach ($allLocations as $id => $name) {
            $locations[$id] = $name;
        }
        
        $this->set(compact('locations', 'selectedLocationIds'));

        /* ===============================
         * DATE / TIME SPLIT
         * =============================== */
        $this->set([
            'offer'          => $offer,
            'offerRows'      => $offerRows,
            'selectedSkuIds' => $selectedSkuIds,
            'startDate'      => $offer['start_date'],
            'startTime'      => $offer['start_time'],
            'endDate'        => $offer['end_date'],
            'endTime'        => $offer['end_time']
        ]);
    
        /* ===============================
         * CATEGORY + SUBCATEGORY OPTIONS
         * =============================== */
        $options = [];
        
        $categories = $this->Catalog_category->find('all', [
            'conditions' => ['Catalog_category.status' => 1],
            'order'      => ['Catalog_category.name' => 'ASC']
        ]);
        
        foreach ($categories as $cat) {
            $catId   = $cat['Catalog_category']['id'];
            $catName = $cat['Catalog_category']['name'];
        
            $subs = $this->Catalog_subcategory->find('all', [
                'conditions' => [
                    'Catalog_subcategory.cat_id' => $catId,
                    'Catalog_subcategory.status' => 1
                ],
                'order' => ['Catalog_subcategory.name' => 'ASC']
            ]);
        
            if (!empty($subs)) {
                // Grouped options
                $options[$catName] = [];
                foreach ($subs as $s) {
                    // Key must match $offer['cat_id'] if it is a subcategory
                    $options[$catName]['sub_' . $s['Catalog_subcategory']['id']] =
                        $s['Catalog_subcategory']['name'];
                }
            } else {
                // Flat category, key must match $offer['cat_id'] if it is a category
                $options['cat_' . $catId] = $catName;
            }
        }
        
        $selectedCategory = null;
        
        if (!empty($offer['subcat_id'])) {
            // Subcategory exists → select subcategory
            $selectedCategory = 'sub_' . $offer['subcat_id'];
        } elseif (!empty($offer['cat_id'])) {
            // Only category exists → select category
            $selectedCategory = 'cat_' . $offer['cat_id'];
        }
        
        $this->set(compact('options', 'selectedCategory'));

    
        /* ===============================
         * LOAD ALL PRODUCTS (CATALOG)
         * =============================== */
        $users = $this->Catalog_product->find('all', [
            'conditions' => ['Catalog_product.status' => 1],
            'order'      => ['Catalog_product.name' => 'ASC']
        ]);
        $this->set(compact('users'));
    
        /* ===============================
         * UPDATE OFFER (POST REQUEST)
         * =============================== */
        if ($this->request->is('post')) {
    
            $applyType  = $this->request->data('type');
            $checkedData = json_decode($this->request->data('checkedData'), true);
            $location = $this->request->data('location');
            
            // normalize to array
            if (!is_array($location)) {
                $location = [$location];
            }
            
            if (empty($location)) {
                echo json_encode(['status' => false, 'msg' => 'Location required']);
                return;
            }
            $itemsToSave = [];
            
            /* ===========================================================
             * CASE 1️⃣ : CATEGORY BASED OFFER
             * =========================================================== */
            if ($applyType === 'category') {
            
                $categoryInput = $this->request->data('category');
            
                // ---------- CATEGORY ----------
                if (strpos($categoryInput, 'cat_') === 0) {
            
                    $category_id = (int) str_replace('cat_', '', $categoryInput);
            
                    $cat = $this->Catalog_category->findById($category_id);
                    $category_name = $cat ? $cat['Catalog_category']['name'] : null;
            
                    $products = $this->Catalog_product->find('all', [
                        'conditions' => [
                            'cat_id' => $category_id,
                            'status' => 1
                        ]
                    ]);
            
                    foreach ($products as $p) {
                        $itemsToSave[] = [
                            'sku_id'      => $p['Catalog_product']['id'],
                            'sku_name'    => $p['Catalog_product']['name'],
                            'cat_id'      => $category_id,
                            'cat_name'    => $category_name,
                            'subcat_id'   => null,
                            'subcat_name' => null
                        ];
                    }
                }
            
                // ---------- SUBCATEGORY ----------
                elseif (strpos($categoryInput, 'sub_') === 0) {
            
                    $subcategory_id = (int) str_replace('sub_', '', $categoryInput);
            
                    $subcat = $this->Catalog_subcategory->findById($subcategory_id);
            
                    if ($subcat) {
                        $subcategory_name = $subcat['Catalog_subcategory']['name'];
                        $category_id      = $subcat['Catalog_subcategory']['cat_id'];
                        $category_name    = $this->Catalog_category->field('name', ['id' => $category_id]);
                    }
            
                    $products = $this->Catalog_product->find('all', [
                        'conditions' => [
                            'cat_id'    => $category_id,
                            'subcat_id' => $subcategory_id,
                            'status'    => 1
                        ]
                    ]);
            
                    foreach ($products as $p) {
                        $itemsToSave[] = [
                            'sku_id'      => $p['Catalog_product']['id'],
                            'sku_name'    => $p['Catalog_product']['name'],
                            'cat_id'      => $category_id,
                            'cat_name'    => $category_name,
                            'subcat_id'   => $subcategory_id,
                            'subcat_name' => $subcategory_name
                        ];
                    }
                }
            }
            
            /* ===========================================================
             * CASE 2️⃣ : ITEM BASED OFFER
             * =========================================================== */
            elseif ($applyType === 'item' && !empty($checkedData)) {
            
                foreach ($checkedData as $i) {
                    $itemsToSave[] = [
                        'sku_id'      => $i['id'],
                        'sku_name'    => $i['sku_name'],
                        'cat_id'      => $i['cat_id'],
                        'cat_name'    => $i['cat_name'],
                        'subcat_id'   => $i['subcat_id'],
                        'subcat_name' => $i['subcat_name']
                    ];
                }
            }
            
            if($itemsToSave){
                
                $this->Offer->updateAll(
                    [
                        'Offer.status'     => 0,
                        'Offer.sync'       => 0,
                        'Offer.local_sync' => 0
                    ],
                    [
                        'Offer.offer_id' => $offer_id
                    ]
                );
        
                foreach ($itemsToSave as $product) {
            
                    foreach ($location as $locId) {
                
                        $locationdetail = $this->Location->find('first', [
                            'conditions' => ['Location.id' => $locId]
                        ]);
                
                        $location_name = !empty($locationdetail)
                            ? $locationdetail['Location']['name']
                            : null;
                
                        $this->Offer->create();
                        $this->Offer->save([
                            'Offer' => [
                                'offer_id'      => $offer_id,
                                'name'          => $this->request->data('offer_name'),
                                'offer_type'    => $this->request->data('offer_type'),
                                'item_type'     => $applyType,
                
                                'location_id'   => $locId,
                                'location_name' => $location_name,
                
                                // CATEGORY + SUBCATEGORY (ALWAYS SAVED)
                                'cat_id'        => $product['cat_id'],
                                'cat_name'      => $product['cat_name'],
                                'subcat_id'     => $product['subcat_id'],
                                'subcat_name'   => $product['subcat_name'],
                
                                // ITEM
                                'sku_id'        => $product['sku_id'],
                                'sku_name'      => $product['sku_name'],
                
                                // PERIOD
                                'start_date'    => $this->request->data('start_date'),
                                'start_time'    => $this->request->data('start_time'),
                                'end_date'      => $this->request->data('end_date'),
                                'end_time'      => $this->request->data('end_time'),
                
                                'status'        => 1,
                                'sync'          => 0,
                                'local_sync'    => 0
                            ]
                        ]);
                    }
                }
                echo json_encode([
                    'status' => true,
                    'msg'    => "Offer Updated Successfully"
                ]);
                exit;
            }else{
                echo json_encode([
                    'status' => false,
                    'msg'    => "No Item found"
                ]);
                exit;
            }
            
        }
    }
    
    /**
     * Read last sync times from the CronController's status file.
     */
    private function _getLastSyncTimes()
    {
        $filePath = TMP . 'sync_status.json';
        if (!file_exists($filePath)) {
            return ['push' => null, 'pull' => null];
        }
        return json_decode(file_get_contents($filePath), true) ?: ['push' => null, 'pull' => null];
    }
    
    public function sync_urbanpiper()
    {
        $this->autoRender = false;

        if (!$this->Session->check('Auth.User.id')) {
            $responseArray = array('response_code' => 0, 'response_message' => 'Session expired, please logout and login again');
            echo json_encode($responseArray);
            return;
        }

        if (!$this->request->is('post') || empty($this->request->data['store_id'])) {
            $responseArray = array('response_code' => 0, 'response_message' => 'Invalid request or missing Store ID');
            echo json_encode($responseArray);
            return;
        }

        $store_id = $this->request->data['store_id'];

        $this->loadModel('Catalog_product');
        $this->loadModel('Catalog_product_tax');
        $this->loadModel('Catalog_category');

        $products = array();
        $categories = array();

        $fetchProducts = "SELECT 
            cp.id,
            cp.name as product_name,
            cp.cat_id,
            cp.cat_name,
            cp.subcat_id,
            cp.subcat_name,
            cp.description,
            cp.food_type,
            cpb.price as price,
            cp.markup_price,
            cp.weight,
            cp.serves_people,
            cp.image,
            cp.created
            FROM catalog_product cp
            INNER JOIN catalog_product_branches cpb ON cp.id = cpb.product_id
            WHERE cp.status = 1 
            AND cpb.status = 1
            AND cpb.location_id = " . $store_id . "
            AND cp.price != 0 and cp.food_type IN (0,1)
            ORDER BY cp.id ASC";
            

        $productResult = $this->Catalog_product->query($fetchProducts);

        if (!$productResult) {
            $responseArray = array('response_code' => 0, 'response_message' => 'Database I/O error: Unable to fetch products');
            echo json_encode($responseArray);
            return;
        }

        foreach ($productResult as $row) {
            $product_id = $row['cp']['id'];
            $product_name = $row['cp']['product_name'];
            $cat_id = $row['cp']['cat_id'];
            $cat_name = $row['cp']['cat_name'];
            $price = $up_price = $row['cpb']['price'] ?? 0;
            $markup_price = $row['cp']['markup_price'];
            

            $description = $row['cp']['description'];

            if ($row['cp']['food_type'] == 0) {
                $food_type = 1;
            } elseif ($row['cp']['food_type'] == 1) {
                $food_type = 2;
            } else {
                $food_type = 1;
            }

            $image = $row['cp']['image'];
            $weight = $row['cp']['weight'];

            $taxQuery = "SELECT tax_name, tax_percentage 
                        FROM catalog_product_tax 
                        WHERE status!=0 and product_id = " . $product_id;
            $taxResult = $this->Catalog_product_tax->query($taxQuery);

            $tax_name = '';
            if (!empty($taxResult)) {
                $taxes = array();
                foreach ($taxResult as $tax) {
                    $taxes[] = $tax['catalog_product_tax']['tax_name'] . ' (' . $tax['catalog_product_tax']['tax_percentage'] . '%)';
                }
                $tax_name = implode(', ', $taxes);
            }
            $productImageUrl = '';
            if ($image != '' && $image != 'NULL') {
                $productImageUrl = Router::url(
                    '/uploads/product_images/' . $image,
                    true
                );
            }
            $products[] = array(
                'id' => $product_id,
                'product_name' => $product_name,
                'price' => $price,
                'markup_price' => $markup_price,
                'up_price' => $up_price,
                'cat_id' => $cat_id,
                'cat_name' => $cat_name,
                'description' => $description,
                'image' => $productImageUrl,
                'food_type' => $food_type,
                'weight' => $weight,
                'tax_name' => $tax_name
            );
        }

        $fetchCategories = "SELECT 
            cc.id,
            cc.name as category_name,
            cc.image
            FROM catalog_category cc
            INNER JOIN catalog_category_branches ccb ON cc.id = ccb.category_id
            WHERE cc.status = 1
            AND ccb.status = 1
            AND ccb.location_id = " . $store_id . "
            ORDER BY cc.name ASC";

        $categoryResult = $this->Catalog_category->query($fetchCategories);

        if (!$categoryResult) {
            $responseArray = array('response_code' => 0, 'response_message' => 'Database I/O error: Unable to fetch categories');
            echo json_encode($responseArray);
            return;
        }


        foreach ($categoryResult as $row) {
            $categoryImageUrl = '';
            if ($row['cc']['image'] != '' && $row['cc']['image'] != 'NULL') {
                $categoryImageUrl = Router::url(
                    '/uploads/category_images/' . $row['cc']['image'],
                    true
                );
            }
            $categories[] = array(
                'id' => $row['cc']['id'],
                'category_name' => $row['cc']['category_name'],
                'description' => '',
                'image' => $categoryImageUrl
            );
        }


        $upoptiongroups = array();
        $upoptions = array();
        // if (!empty($products)) {
            // $addonProductIds = array();
            // foreach ($products as $prod) {
            //     $addonProductIds[] = $prod['id'];
            // }

            // if (!empty($addonProductIds)) {
            //     $productIdsStr = implode(",", $addonProductIds);

            //     // $fetchAddons = "SELECT 
            //     //     cpa.product_id,
            //     //     cpa.name as addon_name,
            //     //     cpa.id as addon_id,
            //     //     cp.name as product_name
            //     //     FROM catalog_product_addon cpa
            //     //     JOIN catalog_product cp ON cpa.product_id = cp.id
            //     //     WHERE cpa.status=1 and cp.status=1 and cpa.product_id IN ($productIdsStr) ";

            //     // $addonResult = $this->Catalog_product_addon->query($fetchAddons);

            //     // if (!empty($addonResult)) {
            //         // $addonsByProduct = array();
            //         // foreach ($addonResult as $addon) {
            //         //     $pid = $addon['cpa']['product_id'];
            //         //     if (!isset($addonsByProduct[$pid])) {
            //         //         $addonsByProduct[$pid] = array(
            //         //             'product_name' => $addon['cp']['product_name'],
            //         //             'addons' => array()
            //         //         );
            //         //     }
            //         //     $addonsByProduct[$pid]['addons'][] = array(
            //         //         'id' => $addon['cpa']['addon_id'],
            //         //         'name' => $addon['cpa']['addon_name']
            //         //     );
            //         // }

            //         foreach ($addonsByProduct as $productId => $addonData) {
            //             $upoptiongroups[] = array(
            //                 "ref_id" => "og_" . $productId,
            //                 "title" => $addonData['product_name'] . " - Addons",
            //                 "active" => true,
            //                 "description" => "Add-ons for " . $addonData['product_name'],
            //                 "min_selectable" => floatval(0),
            //                 "max_selectable" => floatval(-1),
            //                 "sort_order" => floatval(0),
            //                 "ref_title" => $addonData['product_name'] . " - Addons",
            //                 "display_inline" => true,
            //                 "item_ref_ids" => (string) $productId,
            //                 "clear_opt_grp_ref_ids" => true
            //             );

            //             foreach ($addonData['addons'] as $addon) {
            //                 $upoptions[] = array(
            //                     "ref_id" => "opt_" . $addon['id'],
            //                     "title" => $addon['name'],
            //                     "ref_title" => $addon['name'],
            //                     "description" => "",
            //                     "weight" => 0,
            //                     "available" => true,
            //                     "recommended" => false,
            //                     "price" => floatval(0),
            //                     "sold_at_store" => true,
            //                     "sort_order" => floatval(0),
            //                     "clear_opt_grp_ref_ids" => true,
            //                     "opt_grp_ref_ids" => "og_" . $productId,
            //                     "food_type" => 0
            //                 );
            //             }
            //         }
            //     }
            // }
        // }
        $upcategories = array();
        $upproducts = array();
        $taxprod = array();
        $uptaxes = array();
        $upcharges = array();

        // if (!empty($products) && !empty($categories)) {
        //     foreach ($categories as $categ) {
        //         $upcategories[] = array(
        //             "ref_id" => $categ['id'],
        //             "name" => $categ['category_name'],
        //             "description" => "",
        //             "sort_order" => 0,
        //             "active" => true,
        //             "img_url" => $categ['image'],
        //             "parent_ref_id" => ""
        //         );
        //     }

        //     foreach ($products as $prod) {
        //         $taxprod[] = $prod['id'];

        //         $upproducts[] = array(
        //             "ref_id" => $prod['id'],
        //             "title" => $prod['product_name'],
        //             "available" => true,
        //             "description" => $prod['description'] ? $prod['description'] : "",
        //             "sold_at_store" => true,
        //             "sort_order" => 0,
        //             "price" => floatval($prod['up_price']),
        //             "markup_price" => floatval($prod['up_price']),
        //             "current_stock" => -1,
        //             "recommended" => false,
        //             "food_type" => intval($prod['food_type']),
        //             "category_ref_ids" => array($prod['cat_id']),
        //             "fulfillment_modes" => array("delivery"),
        //             "img_url" => $prod['image']
        //         );
        //     }
        
        if (!empty($products) && !empty($categories)) {
        
            $upcategories = [];
            $upproducts = [];
            $taxprod = [];
        
            // Step 1: Collect category IDs that have products
            $usedCategoryIds = [];
        
            foreach ($products as $prod) {
        
                $usedCategoryIds[] = $prod['cat_id']; // collect category id
                $taxprod[] = $prod['id'];
        
                $upproducts[] = array(
                    "ref_id" => $prod['id'],
                    "title" => $prod['product_name'],
                    "available" => true,
                    "description" => !empty($prod['description']) ? $prod['description'] : "",
                    "sold_at_store" => true,
                    "sort_order" => 0,
                    "price" => floatval($prod['up_price']),
                    "markup_price" => floatval($prod['up_price']),
                    "current_stock" => -1,
                    "recommended" => false,
                    "food_type" => intval($prod['food_type']),
                    "category_ref_ids" => array($prod['cat_id']),
                    "fulfillment_modes" => array("delivery"),
                    "img_url" => $prod['image']
                );
            }
        
            // Remove duplicate category IDs
            $usedCategoryIds = array_unique($usedCategoryIds);
        
            // Step 2: Add only categories that exist in usedCategoryIds
            foreach ($categories as $categ) {
        
                if (in_array($categ['id'], $usedCategoryIds)) {
        
                    $upcategories[] = array(
                        "ref_id" => $categ['id'],
                        "name" => $categ['category_name'],
                        "description" => "",
                        "sort_order" => 0,
                        "active" => true,
                        "img_url" => $categ['image'],
                        "parent_ref_id" => ""
                    );
                }
            }
        

            $totalTaxPercentage = 0;
            if (!empty($taxprod)) {
                $firstProductId = $taxprod[0];
                $taxQuery = "SELECT SUM(tax_percentage) as total_tax 
                            FROM catalog_product_tax 
                            WHERE status=1 and product_id = " . $firstProductId;
                $taxResult = $this->Catalog_product_tax->query($taxQuery);
                if (!empty($taxResult)) {
                    $totalTaxPercentage = floatval($taxResult[0][0]['total_tax']);
                }
            }

            $halfTax = $totalTaxPercentage / 2;

            if ($totalTaxPercentage > 0) {
                $structure_cgst = array("value" => $halfTax);
                $uptaxes[] = array(
                    "code" => "CGST_P",
                    "title" => "CGST",
                    "active" => true,
                    "description" => "CGST",
                    "structure" => $structure_cgst,
                    "item_ref_ids" => $taxprod
                );

                $structure_sgst = array("value" => $halfTax);
                $uptaxes[] = array(
                    "code" => "SGST_P",
                    "title" => "SGST",
                    "active" => true,
                    "description" => "SGST",
                    "structure" => $structure_sgst,
                    "item_ref_ids" => $taxprod
                );
            }

            $structurechgdcf = array("value" => 20);
            $upcharges[] = array(
                "code" => "DC_F",
                "title" => "Delivery Charge",
                "active" => true,
                "description" => "Delivery Charge",
                "structure" => $structurechgdcf,
                "fulfillment_modes" => array('delivery'),
                "item_ref_ids" => $taxprod
            );

            $structurechgpcp = array(
                "applicable_on" => "order.order_subtotal",
                "value" => 10
            );
            $upcharges[] = array(
                "code" => "PC_P",
                "title" => "Packaging Charge",
                "active" => true,
                "description" => "Packaging Charge",
                "structure" => $structurechgpcp,
                "fulfillment_modes" => array('delivery'),
                "item_ref_ids" => $taxprod
            );
        } else {
            echo json_encode(array('response_code' => 0, 'response_message' => 'No Data To Sync'));
            return;
        }
        $data = array();
        if (!empty($upcategories)) {
            $data["categories"] = $upcategories;
        }
        if (!empty($upproducts)) {
            $data["items"] = $upproducts;
        }
        if (!empty($upoptiongroups)) {
            $data["option_groups"] = $upoptiongroups;
        }
        if (!empty($upoptions)) {
            $data["options"] = $upoptions;
        }
        if (!empty($uptaxes)) {
            $data["taxes"] = $uptaxes;
        }
        if (!empty($upcharges)) {
            $data["charges"] = $upcharges;
        }

        $data["flush_items"] = true;
        $data["flush_options"] = true;

        $url = "https://api.urbanpiper.com/external/api/v1/inventory/locations/" . $store_id . "/";

        $retry_attempt = 0;
        $retry_status = 0;
        $json = json_encode($data);
        // echo $json;
        // exit;

        $limitQuery = "SELECT status, retry_attempt FROM urbanpiper_limits WHERE event_code = 'stop_api' LIMIT 1";
        $limitResult = $this->Catalog_product->query($limitQuery);

        if (!empty($limitResult)) {
            $retry_attempt = intval($limitResult[0]['urbanpiper_limits']['retry_attempt']);
            $retry_status = intval($limitResult[0]['urbanpiper_limits']['status']);
        }

        if ($retry_attempt < 3 && $retry_status == 0) {
            $json = json_encode($data);
            App::uses('HttpSocket', 'Network/Http');
            $http = new HttpSocket();

            $request = array(
                'header' => array(
                    'Authorization' => 'apikey biz_adm_egGcwzZpmqZk:1dda18a8837267a9ae5d630ed67fe220f517b911',
                    'Content-Type' => 'application/json'
                )
            );

            try {
                $response = $http->post($url, $json, $request);
                $httpcode = $http->response['status']['code'];

                if ($httpcode >= 500) {
                    $retry_attempt++;
                    $error = array(
                        'status' => 'error',
                        'reference' => 'NA',
                        'error' => $httpcode . ' error'
                    );
                    $response = json_encode($error);

                    if ($retry_attempt == 3) {
                        $updateQuery = "UPDATE urbanpiper_limits 
                                       SET status = 1, 
                                           event_name = 'Catalog Configuration Response',
                                           retry_attempt = 0,
                                           remarks = '" . addslashes($response) . "',
                                           modified = NOW()
                                       WHERE event_code = 'stop_api'";
                    } else {
                        $updateQuery = "UPDATE urbanpiper_limits 
                                       SET event_name = 'Catalog Configuration Response',
                                           retry_attempt = " . $retry_attempt . ",
                                           remarks = '" . addslashes($response) . "',
                                           modified = NOW()
                                       WHERE event_code = 'stop_api'";
                    }
                    $this->Catalog_product->query($updateQuery);
                }

                if ($httpcode == 401) {
                    $error = array(
                        'status' => 'error',
                        'reference' => 'NA',
                        'error' => $httpcode . ' error - Authentication failed'
                    );
                    $response = json_encode($error);
                }

                $responseEscaped = addslashes($response);
                $insertQuery = "INSERT INTO urbanpiper_response 
                               (response, event, event_type, created) 
                               VALUES ('" . $responseEscaped . "', 'Catalog Configuration Response', '2', NOW())";
                $this->Catalog_product->query($insertQuery);

                $responseData = json_decode($response);
                if (isset($responseData->status) && $responseData->status == 'success') {
                    echo json_encode(array('response_code' => 1, 'response_message' => 'Status: ' . $responseData->status . ', Reference Id: ' . $responseData->reference));
                } else {
                    echo $response;
                }

            } catch (Exception $e) {
                echo json_encode(array('response_code' => 0, 'response_message' => "Error: " . $e->getMessage()));
            }

        } else {
            echo json_encode(array('response_code' => 0, 'response_message' => "Sorry, your API is blocked. Please reset retry counter in urbanpiper_limits table."));
        }
    }
    
    
// ============================================================
// SERVICE PURCHASE ORDER controller functions
// Append to DashboardController.php before the final closing brace
// ============================================================

    // ─────────────────────────────────────────────────────────────────────────
    // Helpers shared by all SPO functions
    // ─────────────────────────────────────────────────────────────────────────
    private function _spoModels() {
        $this->loadModel('Service_purchase_order');
        $this->loadModel('Service_purchase_order_item');
        $this->loadModel('Inventory_vendor');
    }

    private function _spoGenerateId() {
        do {
            $id = 'SPO' . date('Ymd') . rand(100, 999);
            $exists = $this->Service_purchase_order->find('first', array(
                'conditions' => array('Service_purchase_order.spo_id' => $id),
                'fields'     => array('Service_purchase_order.id'),
            ));
        } while ($exists);
        return $id;
    }

    private function _spoStatusLabel($s) {
        $map = array(0=>'Cancelled', 1=>'Submitted', 2=>'Approved', 3=>'Processed');
        return isset($map[$s]) ? $map[$s] : 'Unknown';
    }

    private function _spoServices() {
        $rows = $this->Service_purchase_order->query(
            "SELECT id, name FROM services WHERE status=1 ORDER BY name ASC"
        );
        $out = array();
        foreach ($rows as $r) {
            $k = isset($r['services']['id']) ? $r['services']['id'] : $r[0]['id'];
            $v = isset($r['services']['name']) ? $r['services']['name'] : $r[0]['name'];
            $out[$k] = $v;
        }
        return $out;
    }

    private function _spoVendors() {
        $rows = $this->Inventory_vendor->find('list', array(
            'conditions' => array('Inventory_vendor.status' => 1),
            'fields'     => array('Inventory_vendor.id', 'Inventory_vendor.company'),
            'order'      => array('Inventory_vendor.company ASC'),
        ));
        return $rows;
    }

    private function _spoStores() {
        $this->loadModel('Location');
        $authUser = $this->Session->read('Auth.User');
        $role     = $authUser['role'] ?? '';
        $locIds   = $authUser['location_ids'] ?? 0;
        $conds    = array('Location.status' => 1);
        if ($role !== 'admin' && $locIds) {
            $conds['Location.id'] = array_map('trim', explode(',', $locIds));
        }
        return $this->Location->find('all', array('conditions' => $conds));
    }
    
    // ─────────────────────────────────────────────────────────────────────────
    // LIST
    // ─────────────────────────────────────────────────────────────────────────
    public function service_po_list() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'users';
        $this->_spoModels();

        $authUser = $this->Session->read('Auth.User');
        $role     = $authUser['role'] ?? '';
        $locIds   = $authUser['location_ids'] ?? 0;

        $startDate = date('Y-m-01');
        $endDate   = date('Y-m-d');

        if ($this->request->is(array('post','put'))) {
            $dr = $this->request->data('daterange');
            if ($dr) {
                $parts = explode(' - ', $dr);
                $startDate = date('Y-m-d', strtotime(trim($parts[0])));
                $endDate   = date('Y-m-d', strtotime(trim($parts[1])));
            }
        }

        $storeFilter  = $this->request->data('Search.store')  ?: null;
        $vendorFilter = $this->request->data('Search.vendor') ?: null;
        $statusFilter = $this->request->data('Search.status');

        $where  = "WHERE spo.status != 0";
        $where .= " AND DATE(spo.created) BETWEEN '$startDate' AND '$endDate'";
        if ($storeFilter)  $where .= " AND spo.location_id = " . (int)$storeFilter;
        elseif ($role !== 'admin' && $locIds) $where .= " AND spo.location_id IN ($locIds)";
        if ($vendorFilter) $where .= " AND spo.vendor_id = " . (int)$vendorFilter;
        if ($statusFilter !== null && $statusFilter !== '') $where .= " AND spo.status = " . (int)$statusFilter;

        $rows = $this->Service_purchase_order->query("
            SELECT spo.id, spo.spo_id, spo.vendor_name, spo.location_name,
                   spo.service_type_name, spo.total_amount, spo.approved_amount,
                   spo.processed_amount, spo.status, spo.created, spo.created_by_name,
                   spo.period_from, spo.period_to
            FROM service_purchase_orders spo
            $where
            ORDER BY spo.id DESC
        ");

        $spos = array();
        foreach ($rows as $r) {
            $row = isset($r['spo']) ? $r['spo'] : $r['service_purchase_orders'];
            $spos[] = array(
                'id'               => $row['id'],
                'spo_id'           => $row['spo_id'],
                'vendor'           => $row['vendor_name'],
                'store'            => $row['location_name'],
                'service_type'     => $row['service_type_name'],
                'total_amount'     => $row['total_amount'],
                'approved_amount'  => $row['approved_amount'],
                'processed_amount' => $row['processed_amount'],
                'status'           => (int)$row['status'],
                'status_label'     => $this->_spoStatusLabel((int)$row['status']),
                'created'          => $row['created'],
                'created_by'       => $row['created_by_name'],
                'period_from'      => $row['period_from'],
                'period_to'        => $row['period_to'],
            );
        }

        $stores  = $this->_spoStores();
        $vendors = $this->_spoVendors();
        $this->set(compact('spos','stores','vendors','startDate','endDate'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // CREATE FORM
    // ─────────────────────────────────────────────────────────────────────────
    public function create_service_po() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'users';
        $this->_spoModels();
        $services = $this->_spoServices();
        $vendors  = $this->_spoVendors();
        $stores   = $this->_spoStores();
        $this->set(compact('services','vendors','stores'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // SAVE (AJAX)
    // ─────────────────────────────────────────────────────────────────────────
    public function add_service_po() {
        $this->autoRender = false;
        $this->_spoModels();

        if (!$this->request->is('post')) {
            echo json_encode(array('status'=>false,'message'=>'POST required'));
            return;
        }

        $authUser    = $this->Session->read('Auth.User');
        $data        = $this->request->data;
        $items       = isset($data['items']) ? $data['items'] : array();

        if (empty($items)) {
            echo json_encode(array('status'=>false,'message'=>'At least one line item required'));
            return;
        }

        $vendorId   = (int)($data['vendor_id'] ?? 0);
        $vendorRow  = $this->Inventory_vendor->find('first', array(
            'conditions' => array('Inventory_vendor.id' => $vendorId),
            'fields'     => array('Inventory_vendor.id','Inventory_vendor.company'),
        ));
        $vendorName = $vendorRow ? $vendorRow['Inventory_vendor']['company'] : '';

        $serviceTypeId   = (int)($data['service_type_id'] ?? 0);
        $serviceRow      = $this->Service_purchase_order->query(
            "SELECT name FROM services WHERE id=" . (int)$serviceTypeId . " LIMIT 1"
        );
        $serviceTypeName = !empty($serviceRow) ? ($serviceRow[0]['services']['name'] ?? $serviceRow[0][0]['name'] ?? '') : '';

        $storeId   = (int)($data['location_id'] ?? 0);
        $this->loadModel('Location');
        $locRow    = $this->Location->find('first', array('conditions'=>array('Location.id'=>$storeId),'fields'=>array('Location.id','Location.name')));
        $storeName = $locRow ? $locRow['Location']['name'] : '';

        $spoId = $this->_spoGenerateId();

        // Calculate totals from items
        $subtotal  = 0; $totalTax = 0; $totalDiscount = 0;
        foreach ($items as $item) {
            $qty      = (float)($item['quantity'] ?? 1);
            $price    = (float)($item['unit_price'] ?? 0);
            $disc     = (float)($item['discount_value'] ?? 0);
            $taxPct   = (float)($item['tax_percentage'] ?? 0);
            $base     = ($qty * $price) - $disc;
            $taxVal   = round($base * $taxPct / 100, 2);
            $subtotal      += $qty * $price;
            $totalDiscount += $disc;
            $totalTax      += $taxVal;
        }
        $totalAmount = round($subtotal - $totalDiscount + $totalTax, 2);

        $header = array('Service_purchase_order' => array(
            'spo_id'            => $spoId,
            'vendor_id'         => $vendorId,
            'vendor_name'       => $vendorName,
            'location_id'       => $storeId,
            'location_name'     => $storeName,
            'service_type_id'   => $serviceTypeId,
            'service_type_name' => $serviceTypeName,
            'description'       => trim($data['description'] ?? ''),
            'period_from'       => $data['period_from'] ?: null,
            'period_to'         => $data['period_to']   ?: null,
            'subtotal'          => round($subtotal, 2),
            'discount'          => round($totalDiscount, 2),
            'total_tax'         => round($totalTax, 2),
            'total_amount'      => $totalAmount,
            'remarks'           => trim($data['remarks'] ?? ''),
            'status'            => 1,
            'created_by'        => $authUser['id'] ?? 0,
            'created_by_name'   => $authUser['name'] ?? '',
        ));

        $this->Service_purchase_order->create();
        if (!$this->Service_purchase_order->save($header)) {
            echo json_encode(array('status'=>false,'message'=>'Failed to save SPO header'));
            return;
        }

        foreach ($items as $item) {
            $qty     = (float)($item['quantity'] ?? 1);
            $price   = (float)($item['unit_price'] ?? 0);
            $disc    = (float)($item['discount_value'] ?? 0);
            $taxPct  = (float)($item['tax_percentage'] ?? 0);
            $base    = ($qty * $price) - $disc;
            $taxVal  = round($base * $taxPct / 100, 2);
            $total   = round($base + $taxVal, 2);

            $this->Service_purchase_order_item->create();
            $this->Service_purchase_order_item->save(array('Service_purchase_order_item' => array(
                'spo_id'         => $spoId,
                'service_name'   => trim($item['service_name'] ?? ''),
                'description'    => trim($item['description'] ?? ''),
                'unit'           => trim($item['unit'] ?? 'Lump Sum'),
                'quantity'       => $qty,
                'unit_price'     => $price,
                'discount_value' => $disc,
                'tax_percentage' => $taxPct,
                'tax_value'      => $taxVal,
                'total_amount'   => $total,
                'status'         => 1,
            )));
        }

        echo json_encode(array('status'=>true,'spo_id'=>$spoId,'message'=>'Service PO created successfully'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // VIEW
    // ─────────────────────────────────────────────────────────────────────────
    public function view_service_po() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'users';
        $this->_spoModels();

        $spoId = isset($_GET['id']) ? trim($_GET['id']) : '';
        if (!$spoId) { $this->redirect(array('action'=>'service_po_list')); return; }

        $spo   = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId),
        ));
        $items = $this->Service_purchase_order_item->find('all', array(
            'conditions' => array('Service_purchase_order_item.spo_id' => $spoId,
                                  'Service_purchase_order_item.status' => 1),
        ));

        if (empty($spo)) { $this->redirect(array('action'=>'service_po_list')); return; }
        $this->set(compact('spo','items'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // EDIT FORM (status=1 only)
    // ─────────────────────────────────────────────────────────────────────────
    public function edit_service_po() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'users';
        $this->_spoModels();

        $spoId = isset($_GET['id']) ? trim($_GET['id']) : '';
        $spo   = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId,
                                  'Service_purchase_order.status'  => 1),
        ));
        if (empty($spo)) {
            $this->Session->setFlash('SPO not found or cannot be edited (already approved/processed).');
            $this->redirect(array('action'=>'service_po_list')); return;
        }
        $items    = $this->Service_purchase_order_item->find('all', array(
            'conditions' => array('Service_purchase_order_item.spo_id' => $spoId,
                                  'Service_purchase_order_item.status'  => 1),
        ));
        $services = $this->_spoServices();
        $vendors  = $this->_spoVendors();
        $stores   = $this->_spoStores();
        $this->set(compact('spo','items','services','vendors','stores'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // UPDATE (AJAX)
    // ─────────────────────────────────────────────────────────────────────────
    public function update_service_po() {
        $this->autoRender = false;
        $this->_spoModels();

        if (!$this->request->is('post')) {
            echo json_encode(array('status'=>false,'message'=>'POST required'));
            return;
        }

        $data  = $this->request->data;
        $spoId = trim($data['spo_id'] ?? '');
        $spo   = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId,
                                  'Service_purchase_order.status'  => 1),
        ));
        if (empty($spo)) {
            echo json_encode(array('status'=>false,'message'=>'SPO not found or not editable'));
            return;
        }

        $items = isset($data['items']) ? $data['items'] : array();
        if (empty($items)) {
            echo json_encode(array('status'=>false,'message'=>'At least one line item required'));
            return;
        }

        $vendorId   = (int)($data['vendor_id'] ?? 0);
        $vendorRow  = $this->Inventory_vendor->find('first', array(
            'conditions' => array('Inventory_vendor.id' => $vendorId),
            'fields'     => array('Inventory_vendor.id','Inventory_vendor.company'),
        ));
        $vendorName = $vendorRow ? $vendorRow['Inventory_vendor']['company'] : '';

        $serviceTypeId = (int)($data['service_type_id'] ?? 0);
        $serviceRow    = $this->Service_purchase_order->query(
            "SELECT name FROM services WHERE id=" . (int)$serviceTypeId . " LIMIT 1"
        );
        $serviceTypeName = !empty($serviceRow) ? ($serviceRow[0]['services']['name'] ?? $serviceRow[0][0]['name'] ?? '') : '';

        $storeId = (int)($data['location_id'] ?? 0);
        $this->loadModel('Location');
        $locRow  = $this->Location->find('first', array('conditions'=>array('Location.id'=>$storeId)));
        $storeName = $locRow ? $locRow['Location']['name'] : '';

        $subtotal = 0; $totalTax = 0; $totalDiscount = 0;
        foreach ($items as $item) {
            $qty  = (float)($item['quantity'] ?? 1);
            $price= (float)($item['unit_price'] ?? 0);
            $disc = (float)($item['discount_value'] ?? 0);
            $taxPct=(float)($item['tax_percentage'] ?? 0);
            $base = ($qty * $price) - $disc;
            $subtotal      += $qty * $price;
            $totalDiscount += $disc;
            $totalTax      += round($base * $taxPct / 100, 2);
        }
        $totalAmount = round($subtotal - $totalDiscount + $totalTax, 2);

        $this->Service_purchase_order->id = $spo['Service_purchase_order']['id'];
        $this->Service_purchase_order->save(array('Service_purchase_order' => array(
            'vendor_id'         => $vendorId,
            'vendor_name'       => $vendorName,
            'location_id'       => $storeId,
            'location_name'     => $storeName,
            'service_type_id'   => $serviceTypeId,
            'service_type_name' => $serviceTypeName,
            'description'       => trim($data['description'] ?? ''),
            'period_from'       => $data['period_from'] ?: null,
            'period_to'         => $data['period_to']   ?: null,
            'subtotal'          => round($subtotal, 2),
            'discount'          => round($totalDiscount, 2),
            'total_tax'         => round($totalTax, 2),
            'total_amount'      => $totalAmount,
            'remarks'           => trim($data['remarks'] ?? ''),
        )));

        // Replace items: soft-delete old, insert new
        $this->Service_purchase_order_item->updateAll(
            array('Service_purchase_order_item.status' => 0),
            array('Service_purchase_order_item.spo_id' => $spoId)
        );

        foreach ($items as $item) {
            $qty    = (float)($item['quantity'] ?? 1);
            $price  = (float)($item['unit_price'] ?? 0);
            $disc   = (float)($item['discount_value'] ?? 0);
            $taxPct = (float)($item['tax_percentage'] ?? 0);
            $base   = ($qty * $price) - $disc;
            $taxVal = round($base * $taxPct / 100, 2);
            $this->Service_purchase_order_item->create();
            $this->Service_purchase_order_item->save(array('Service_purchase_order_item' => array(
                'spo_id'         => $spoId,
                'service_name'   => trim($item['service_name'] ?? ''),
                'description'    => trim($item['description'] ?? ''),
                'unit'           => trim($item['unit'] ?? 'Lump Sum'),
                'quantity'       => $qty,
                'unit_price'     => $price,
                'discount_value' => $disc,
                'tax_percentage' => $taxPct,
                'tax_value'      => $taxVal,
                'total_amount'   => round($base + $taxVal, 2),
                'status'         => 1,
            )));
        }

        echo json_encode(array('status'=>true,'message'=>'SPO updated successfully'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // APPROVE (AJAX) — status 1 → 2
    // ─────────────────────────────────────────────────────────────────────────
    public function approve_service_po() {
        $this->autoRender = false;
        $this->_spoModels();

        if (!$this->request->is('post')) {
            echo json_encode(array('status'=>false,'message'=>'POST required'));
            return;
        }

        $authUser = $this->Session->read('Auth.User');
        $data     = $this->request->data;
        $spoId    = trim($data['spo_id'] ?? '');

        $spo = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId,
                                  'Service_purchase_order.status'  => 1),
        ));
        if (empty($spo)) {
            echo json_encode(array('status'=>false,'message'=>'SPO not found or not in Submitted state'));
            return;
        }

        $approvedItems = isset($data['items']) ? $data['items'] : array();
        $totalApproved = 0;

        foreach ($approvedItems as $itemId => $approvedAmt) {
            $amt = (float)$approvedAmt;
            $this->Service_purchase_order_item->id = (int)$itemId;
            $this->Service_purchase_order_item->save(array(
                'Service_purchase_order_item' => array('approved_amount' => $amt)
            ));
            $totalApproved += $amt;
        }

        $this->Service_purchase_order->id = $spo['Service_purchase_order']['id'];
        $this->Service_purchase_order->save(array('Service_purchase_order' => array(
            'status'           => 2,
            'approved_by_id'   => $authUser['id'] ?? 0,
            'approved_by_name' => $authUser['name'] ?? '',
            'approved_on'      => date('Y-m-d H:i:s'),
            'approved_amount'  => round($totalApproved, 2),
        )));

        echo json_encode(array('status'=>true,'message'=>'SPO approved successfully'));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // PROCESS (AJAX) — status 2 → 3
    // ─────────────────────────────────────────────────────────────────────────
    public function process_service_po() {
        $this->autoRender = false;
        $this->_spoModels();

        if (!$this->request->is('post')) {
            echo json_encode(array('status'=>false,'message'=>'POST required'));
            return;
        }

        $authUser  = $this->Session->read('Auth.User');
        $data      = $this->request->data;
        $spoId     = trim($data['spo_id'] ?? '');
        $invoiceNo = trim($data['invoice_no'] ?? '');

        $spo = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId,
                                  'Service_purchase_order.status'  => 2),
        ));
        if (empty($spo)) {
            echo json_encode(array('status'=>false,'message'=>'SPO not found or not in Approved state'));
            return;
        }

        $processedItems = isset($data['items']) ? $data['items'] : array();
        $totalProcessed = 0;

        foreach ($processedItems as $itemId => $processedAmt) {
            $amt = (float)$processedAmt;
            $this->Service_purchase_order_item->id = (int)$itemId;
            $this->Service_purchase_order_item->save(array(
                'Service_purchase_order_item' => array('processed_amount' => $amt)
            ));
            $totalProcessed += $amt;
        }

        $this->Service_purchase_order->id = $spo['Service_purchase_order']['id'];
        $this->Service_purchase_order->save(array('Service_purchase_order' => array(
            'status'            => 3,
            'invoice_no'        => $invoiceNo,
            'invoice_date'      => $data['invoice_date'] ?: null,
            'processed_by_id'   => $authUser['id'] ?? 0,
            'processed_by_name' => $authUser['name'] ?? '',
            'processed_on'      => date('Y-m-d H:i:s'),
            'processed_amount'  => round($totalProcessed, 2),
        )));

        echo json_encode(array('status'=>true,'message'=>'SPO processed successfully'));
    }
    
    // ─────────────────────────────────────────────────────────────────────────
    // REPORT
    // ─────────────────────────────────────────────────────────────────────────
   
    public function service_po_report()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'users';
        $this->_spoModels();

        $authUser = $this->Session->read('Auth.User');
        $role     = $authUser['role'] ?? '';
        $locIds   = $authUser['location_ids'] ?? 0;

        $startDate = date('Y-m-01');
        $endDate   = date('Y-m-d');

        if ($this->request->is(array('post','put'))) {
            $dr = $this->request->data('daterange');
            if ($dr) {
                $parts = explode(' - ', $dr);
                $startDate = date('Y-m-d', strtotime(trim($parts[0])));
                $endDate   = date('Y-m-d', strtotime(trim($parts[1])));
            }
        }

        $storeFilter   = $this->request->data('Search.store')        ?: null;
        $vendorFilter  = $this->request->data('Search.vendor')       ?: null;
        $serviceFilter = $this->request->data('Search.service_type') ?: null;
        $statusFilter  = $this->request->data('Search.status');

        $where  = "WHERE spo.status != 0";
        $where .= " AND DATE(spo.created) BETWEEN '$startDate' AND '$endDate'";
        if ($storeFilter)   $where .= " AND spo.location_id = " . (int)$storeFilter;
        elseif ($role !== 'admin' && $locIds) $where .= " AND spo.location_id IN ($locIds)";
        if ($vendorFilter)  $where .= " AND spo.vendor_id = " . (int)$vendorFilter;
        if ($serviceFilter) $where .= " AND spo.service_type_id = " . (int)$serviceFilter;
        if ($statusFilter !== null && $statusFilter !== '') $where .= " AND spo.status = " . (int)$statusFilter;

        $rows = $this->Service_purchase_order->query("
            SELECT
                spo.spo_id, spo.vendor_name, spo.location_name,
                spo.service_type_name, spo.status,
                spo.total_amount, spo.approved_amount, spo.processed_amount,
                spo.period_from, spo.period_to, spo.invoice_no, spo.created,
                spo.created_by_name,
                COUNT(spoi.id)             AS line_count,
                SUM(spoi.quantity)         AS qty_total,
                SUM(spoi.total_amount)     AS items_total
            FROM service_purchase_orders spo
            LEFT JOIN service_purchase_order_items spoi
                ON spo.spo_id = spoi.spo_id AND spoi.status = 1
            $where
            GROUP BY spo.spo_id
            ORDER BY spo.id DESC
        ");

        $spos = array();
        $grandTotal = array('submitted'=>0,'approved'=>0,'processed'=>0);
        foreach ($rows as $r) {
            $h  = isset($r['spo']) ? $r['spo'] : $r['service_purchase_orders'];
            $ag = $r[0];
            $st = (int)$h['status'];
            $row = array(
                'spo_id'           => $h['spo_id'],
                'vendor'           => $h['vendor_name'],
                'store'            => $h['location_name'],
                'service_type'     => $h['service_type_name'],
                'status'           => $st,
                'status_label'     => $this->_spoStatusLabel($st),
                'total_amount'     => (float)$h['total_amount'],
                'approved_amount'  => (float)$h['approved_amount'],
                'processed_amount' => (float)$h['processed_amount'],
                'period_from'      => $h['period_from'],
                'period_to'        => $h['period_to'],
                'invoice_no'       => $h['invoice_no'],
                'created'          => $h['created'],
                'created_by'       => $h['created_by_name'],
                'line_count'       => $ag['line_count'],
            );
            $spos[] = $row;
            $grandTotal['submitted']  += $row['total_amount'];
            $grandTotal['approved']   += $row['approved_amount'];
            $grandTotal['processed']  += $row['processed_amount'];
        }

        $stores   = $this->_spoStores();
        $vendors  = $this->_spoVendors();
        $services = $this->_spoServices();
        $this->set(compact('spos','stores','vendors','services','grandTotal','startDate','endDate'));
    }

    // ---------------------------------------------------------

    /**
     * AJAX – item lines for a single SPO (Details modal)
     * GET param: spo_id  (varchar, e.g. SPO20260309920)
     */
    public function service_po_report_items()
    {
        if (!$this->Session->check('Auth.User.id')) {
            $this->autoRender = false; 
            $this->response->type('application/json');
            return $this->response->body(json_encode(array('error' => 'Unauthorized')));
        }
        $this->autoRender = false;
        $this->response->type('application/json');
        $this->_spoModels();

        $spo_id = $this->request->query('spo_id') ?? '';
        if (!$spo_id) {
            return $this->response->body(json_encode(array('error' => 'Invalid SPO')));
        }
            

        $iRows = $this->Service_purchase_order_item->query("
            SELECT
                spoi.service_name,
                spoi.description,
                spoi.unit,
                spoi.quantity,
                spoi.unit_price,
                spoi.discount_value,
                spoi.tax_percentage,
                spoi.tax_value,
                spoi.total_amount,
                spoi.approved_amount,
                spoi.processed_amount
            FROM service_purchase_order_items spoi
            WHERE spoi.spo_id = '$spo_id'
              AND spoi.status = 1
            ORDER BY spoi.id ASC
        ");
        $items = array();
        foreach ($iRows as $row) {
            $r  = $row['spoi'] ?? array();
            $r0 = $row[0]      ?? array();

            $items[] = array(
                'service_name'     => $r['service_name']     ?? $r0['service_name']     ?? '',
                'description'      => $r['description']      ?? $r0['description']      ?? '',
                'unit'             => $r['unit']             ?? $r0['unit']             ?? '',
                'quantity'         => (float)($r['quantity']         ?? $r0['quantity']         ?? 0),
                'unit_price'       => (float)($r['unit_price']       ?? $r0['unit_price']       ?? 0),
                'discount_value'   => (float)($r['discount_value']   ?? $r0['discount_value']   ?? 0),
                'tax_percentage'   => (float)($r['tax_percentage']   ?? $r0['tax_percentage']   ?? 0),
                'tax_value'        => (float)($r['tax_value']        ?? $r0['tax_value']        ?? 0),
                'total_amount'     => (float)($r['total_amount']     ?? $r0['total_amount']     ?? 0),
                'approved_amount'  => (float)($r['approved_amount']  ?? $r0['approved_amount']  ?? 0),
                'processed_amount' => (float)($r['processed_amount'] ?? $r0['processed_amount'] ?? 0),
            );
        }

        return $this->response->body(json_encode(array('items' => $items)));
    }
    
    // ─────────────────────────────────────────────────────────────────────────
    // EXPORT CSV
    // ─────────────────────────────────────────────────────────────────────────
    // ── Service PO Report PDF ────────────────────────────────────────────────
    // ── Service PO Report CSV export ────────────────────────────────────────
     public function service_po_export() {
        $this->autoRender = false;
        $this->_spoModels();
        $authUser = $this->Session->read('Auth.User');
        $role     = $authUser['role'] ?? '';
        $locIds   = $authUser['location_ids'] ?? 0;
        $startDate = isset($_GET['from']) ? trim($_GET['from']) : date('Y-m-01');
        $endDate   = isset($_GET['to'])   ? trim($_GET['to'])   : date('Y-m-d');

        $where  = "WHERE spo.status != 0";
        $where .= " AND DATE(spo.created) BETWEEN '$startDate' AND '$endDate'";
        if ($role !== 'admin' && $locIds) $where .= " AND spo.location_id IN ($locIds)";

        $statusMap = [0 => 'Cancelled', 1 => 'Submitted', 2 => 'Approved', 3 => 'Processed'];

        // Fetch SPO-level summary only
        $rows = $this->Service_purchase_order->query("
            SELECT
                spo.spo_id, spo.vendor_name, spo.location_name, spo.service_type_name,
                spo.status, spo.period_from, spo.period_to, spo.invoice_no, spo.created,
                COUNT(spoi.id)              AS item_count,
                SUM(spoi.quantity)          AS qty_total,
                SUM(spoi.unit_price * spoi.quantity)                          AS gross,
                SUM(COALESCE(spoi.discount_value, 0))                         AS discount,
                SUM(spoi.unit_price * spoi.quantity - COALESCE(spoi.discount_value, 0)) AS base,
                SUM(COALESCE(spoi.tax_value, 0))                              AS tax,
                SUM(spoi.total_amount)                                        AS total,
                SUM(spoi.approved_amount)                                     AS approved_amt,
                SUM(spoi.processed_amount)                                    AS processed_amt
            FROM service_purchase_orders spo
            LEFT JOIN service_purchase_order_items spoi
                ON spo.spo_id = spoi.spo_id AND spoi.status = 1
            $where
            GROUP BY spo.spo_id
            ORDER BY spo.id DESC
        ");

        // Collect all SPO IDs
        $spoIds = [];
        foreach ($rows as $r) {
            $spoIds[] = "'" . $r['spo']['spo_id'] . "'";
        }

        // Fetch all item lines for these SPOs in one query
        $itemsMap = [];
        if (!empty($spoIds)) {
            $inList   = implode(',', $spoIds);
            $itemRows = $this->Service_purchase_order->query("
                SELECT
                    spoi.spo_id,
                    spoi.service_name,
                    spoi.unit,
                    spoi.quantity,
                    spoi.unit_price,
                    COALESCE(spoi.discount_value, 0)                                          AS discount,
                    (spoi.unit_price * spoi.quantity - COALESCE(spoi.discount_value, 0))      AS base,
                    spoi.tax_percentage,
                    spoi.tax_value                                                             AS tax,
                    spoi.total_amount                                                          AS total,
                    spoi.approved_amount                                                       AS approved_amt,
                    spoi.processed_amount                                                      AS processed_amt
                FROM service_purchase_order_items spoi
                WHERE spoi.spo_id IN ($inList) AND spoi.status = 1
                ORDER BY spoi.spo_id, spoi.id ASC
            ");

            foreach ($itemRows as $ir) {
                $spoId = $ir['spoi']['spo_id'] ?? $ir[0]['spo_id'] ?? null;
                if (!$spoId) continue;
                $itemsMap[$spoId][] = [
                    'service_name'  => $ir['spoi']['service_name']  ?? $ir[0]['service_name']  ?? '',
                    'unit'          => $ir['spoi']['unit']          ?? $ir[0]['unit']          ?? '',
                    'quantity'      => $ir['spoi']['quantity']      ?? $ir[0]['quantity']      ?? 0,
                    'unit_price'    => $ir['spoi']['unit_price']    ?? $ir[0]['unit_price']    ?? 0,
                    'discount'      => $ir[0]['discount']           ?? 0,
                    'base'          => $ir[0]['base']               ?? 0,
                    'tax_percentage'=> $ir['spoi']['tax_percentage']?? $ir[0]['tax_percentage']?? 0,
                    'tax'           => $ir[0]['tax']                ?? 0,
                    'total'         => $ir['spoi']['total']         ?? $ir[0]['total']         ?? 0,
                    'approved_amt'  => $ir['spoi']['approved_amt']  ?? $ir[0]['approved_amt']  ?? 0,
                    'processed_amt' => $ir['spoi']['processed_amt'] ?? $ir[0]['processed_amt'] ?? 0,
                ];
            }
        }

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="service_po_report_' . date('Ymd') . '.csv"');
        $out = fopen('php://output', 'w');

        // Header row
        fputcsv($out, [
            'SPO ID', 'Vendor', 'Store', 'Service Type', 'Status',
            'Period From', 'Period To', 'Invoice No', 'Created',
            'Items', 'Qty', 'Gross', 'Discount', 'Base', 'Tax',
            'Total', 'Approved Amt', 'Processed Amt'
        ]);

        foreach ($rows as $r) {
            $h    = $r['spo'];
            $calc = $r[0];
            $spoId = $h['spo_id'];

            // SPO summary row
            fputcsv($out, [
                $spoId,
                $h['vendor_name'],
                $h['location_name'],
                $h['service_type_name'],
                $statusMap[(int)$h['status']] ?? '',
                $h['period_from'],
                $h['period_to'],
                $h['invoice_no'],
                $h['created'],
                $calc['item_count']   ?? 0,
                round($calc['qty_total']    ?? 0, 3),
                round($calc['gross']        ?? 0, 2),
                round($calc['discount']     ?? 0, 2),
                round($calc['base']         ?? 0, 2),
                round($calc['tax']          ?? 0, 2),
                round($calc['total']        ?? 0, 2),
                round($calc['approved_amt'] ?? 0, 2),
                round($calc['processed_amt']?? 0, 2),
            ]);

            // Item detail rows — leading columns blank like po_report_v2
            foreach ($itemsMap[$spoId] ?? [] as $item) {
                fputcsv($out, [
                    '',  // SPO ID
                    '',  // Vendor
                    '',  // Store
                    '',  // Service Type
                    '',  // Status
                    '',  // Period From
                    '',  // Period To
                    '',  // Invoice No
                    '',  // Created
                    $item['service_name'],
                    round($item['quantity'],      3),
                    round($item['unit_price'] * $item['quantity'], 2),
                    round($item['discount'],      2),
                    round($item['base'],          2),
                    round($item['tax'],           2),
                    round($item['total'],         2),
                    round($item['approved_amt'],  2),
                    round($item['processed_amt'], 2),
                ]);
            }
        }

        fclose($out);
    }
   
    // ── Single SPO PDF ───────────────────────────────────────────────────────
    public function service_po_pdf() {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(array('controller'=>'dashboard','action'=>'login'));
        }
        $this->layout = 'login';
        $this->_spoModels();

        $spoId = isset($_GET['id']) ? trim($_GET['id']) : '';
        if (!$spoId) {
            return $this->redirect(array('action' => 'service_po_list'));
        }

        $spo = $this->Service_purchase_order->find('first', array(
            'conditions' => array('Service_purchase_order.spo_id' => $spoId),
        ));
        $items = $this->Service_purchase_order_item->find('all', array(
            'conditions' => array(
                'Service_purchase_order_item.spo_id'   => $spoId,
                'Service_purchase_order_item.status'   => 1,
            ),
        ));

        if (empty($spo)) {
            return $this->redirect(array('action' => 'service_po_list'));
        }

        $this->set(compact('spo', 'items'));
        $this->render('service_po_pdf');
    }
    /**
     * C1: Purchase Order Report v2
     * Full PO-level report with proper fields: PO No/ID, date, store, vendor,
     * status, item lines, qty, gross/discount/base/tax/tcs/total,
     * approved/processed/stockin amounts.
     * CSV export identical to view.
     */
    public function po_report_v2()
    {
		
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->layout = "users";

        $startDate = date('m/d/Y', strtotime(date('Y-m-01')));
        $endDate   = date('m/d/Y');

        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            $dates = explode(" - ", $daterange);
            $startDate = date('m/d/Y', strtotime(trim($dates[0])));
            $endDate   = date('m/d/Y', strtotime(trim($dates[1])));
        }
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate   = date('Y-m-d', strtotime($endDate));
        $startDT   = $startdate . ' 00:00:00';
        $endDT     = $enddate   . ' 23:59:59';

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $store_id  = !empty($this->request->data['Search']['store'])  ? (int)$this->request->data['Search']['store']  : null;
        $vendor_id = !empty($this->request->data['Search']['vendor']) ? (int)$this->request->data['Search']['vendor'] : null;
        $status_f  = isset($this->request->data['Search']['status'])  ? $this->request->data['Search']['status']      : '';

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) {
            $where .= " AND ipo.location_id = $store_id";
        } elseif ($userRole !== 'admin') {
            $where .= " AND ipo.location_id IN ($userLocationId)";
        }
        if ($vendor_id) $where .= " AND ipo.vendor_id = $vendor_id";
        if ($status_f !== '') $where .= " AND ipo.status = " . (int)$status_f;

        $statusLabels = [1 => 'Submitted', 2 => 'Approved', 3 => 'Processed', 4 => 'Stocked In'];

        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipo.p_o_id,
                ipo.created AS po_date,
                ipo.location_name AS store,
                ipo.vendor_name AS vendor,
                ipo.status,
                COUNT(ipoi.id) AS item_count,
                SUM(ipoi.sku_quantity) AS qty_total,
				SUM(ipoi.stockin_quantity) as stockin_qty,
                SUM(ipoi.sku_price * ipoi.sku_quantity) AS gross,
                SUM(COALESCE(ipoi.sku_discount_value,0)) AS discount,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
                SUM(COALESCE(ipoi.tcs_amount,0)) AS tcs,
                SUM(ipoi.sku_amount) AS total,
                SUM(ipoi.approved_amount) AS approved_amt,
                SUM(ipoi.approved_total_tax_value) AS approved_tax,
                SUM(ipoi.processed_amount) AS processed_amt,
                SUM(ipoi.processed_total_tax_value) AS processed_tax,
                SUM(ipoi.stockin_amount) AS stockin_amt,
                SUM(ipoi.stockin_total_tax_value) AS stockin_tax
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id AND ipoi.status != 0
            $where
            GROUP BY ipo.p_o_id
            ORDER BY ipo.id DESC
        ");

        $pos = [];
        foreach ($rows as $r) {
            $pos[] = [
                'po_id'        => $r['ipo']['p_o_id'],
                'po_date'      => $r['ipo']['po_date'] ?? $r[0]['po_date'] ?? '',
                'store'        => $r['ipo']['store']   ?? $r[0]['store']   ?? '',
                'vendor'       => $r['ipo']['vendor']  ?? $r[0]['vendor']  ?? '',
                'status'       => $statusLabels[$r['ipo']['status'] ?? 0] ?? 'Unknown',
                'item_count'   => $r[0]['item_count']   ?? 0,
                'qty_total'    => $r[0]['qty_total']    ?? 0,
                'stockin_qty'  => $r[0]['stockin_qty']    ?? 0,
                'gross'        => $r[0]['gross']        ?? 0,
                'discount'     => $r[0]['discount']     ?? 0,
                'base'         => $r[0]['base']         ?? 0,
                'tax'          => $r[0]['tax']          ?? 0,
                'tcs'          => $r[0]['tcs']          ?? 0,
                'total'        => $r[0]['total']        ?? 0,
                'approved_amt' => (float)($r[0]['approved_amt'] ?? 0),
                'processed_amt'=> (float)($r[0]['processed_amt'] ?? 0),
                'stockin_amt'  => (float)($r[0]['stockin_amt']  ?? 0)
            ];
        }

        $conditions = ['status' => 1]; // T14-fix: show all location types in purchase report store dropdown
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $conditions['id IN'] = array_map('trim', explode(',', $userLocationId));
        }
        $stores  = $this->Location->find('all', ['conditions' => $conditions]);
        $vendors = $this->Inventory_vendor->find('list', [
            'conditions' => ['Inventory_vendor.status' => 1],
            'fields' => ['Inventory_vendor.id', 'Inventory_vendor.company'],
            'order'  => ['Inventory_vendor.company ASC']
        ]);

        $this->set('startdate', $startDate . ' - ' . $endDate);
        $this->set(compact('stores', 'vendors', 'pos', 'statusLabels'));
    }

	/**
	 * AJAX: Return item lines for a single PO (called on modal open)
	 */
	public function po_report_v2_items()
	{
		if (!$this->Session->check('Auth.User.id')) {
			return $this->response->body(json_encode(['error' => 'Unauthorized']));
		}
		$this->autoRender = false;
		$this->response->type('application/json');

		$po_id = (int)($this->request->query('po_id') ?? 0);
		if (!$po_id) {
			return $this->response->body(json_encode(['error' => 'Invalid PO']));
		}

		$items = $this->Inventory_purchase_order->query("
			SELECT
				ipoi.sku_name                                                                    AS item_name,
				ipoi.sku_quantity                                                                AS qty,
				ipoi.stockin_quantity                                                            AS stockin_qty,
				(ipoi.sku_price * ipoi.sku_quantity)                                             AS gross,
				COALESCE(ipoi.sku_discount_value, 0)                                             AS discount,
				(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value, 0))      AS base,
				COALESCE(ipoi.sku_total_tax_value, 0)                                            AS tax,
				COALESCE(ipoi.tcs_amount, 0)                                                     AS tcs,
				ipoi.sku_amount                                                                  AS total,
				ipoi.approved_amount   AS approved_amt,
				ipoi.processed_amount  AS processed_amt,
				ipoi.stockin_amount    AS stockin_amt
			FROM inventory_purchase_order_items ipoi
			WHERE ipoi.p_o_id = $po_id AND ipoi.status != 0
			ORDER BY ipoi.id ASC
		");

		$result = [];
		foreach ($items as $row) {
			$r  = $row['ipoi'] ?? [];   // real table columns (sku_name etc.)
			$r0 = $row[0]      ?? [];   // computed/expression columns (gross, discount, base …)

			$result[] = [
				'item_name'     => $r['item_name']             ?? $r0['item_name']     ?? '',
				'qty'           => $r['qty']                   ?? $r0['qty']           ?? 0,
				'stockin_qty'   => $r['stockin_qty']           ?? $r0['stockin_qty']           ?? 0,
				'gross'         => $r0['gross']                ?? 0,   // computed → always in [0]
				'discount'      => $r0['discount']             ?? 0,
				'base'          => $r0['base']                 ?? 0,
				'tax'           => $r['tax']                   ?? $r0['tax']           ?? 0,
				'tcs'           => $r['tcs']                   ?? $r0['tcs']           ?? 0,
				'total'         => $r['total']                 ?? $r0['total']         ?? 0,
				'approved_amt'  => $r['approved_amt']          ?? $r0['approved_amt']  ?? 0,
				'processed_amt' => $r['processed_amt']         ?? $r0['processed_amt'] ?? 0,
				'stockin_amt'   => $r['stockin_amt']           ?? $r0['stockin_amt']   ?? 0,
			];
		}

		return $this->response->body(json_encode(['items' => $result]));
	}

    public function po_report_v2_export()
	{
		$this->autoRender = false;
		$date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
		$dates      = explode(" - ", $date_range);
		$startdate  = date('Y-m-d', strtotime(trim($dates[0])));
		$enddate    = date('Y-m-d', strtotime(trim($dates[1])));
		$startDT    = $startdate . ' 00:00:00';
		$endDT      = $enddate   . ' 23:59:59';
		$store_id   = !empty($_GET['store'])  ? (int)$_GET['store']  : null;
		$vendor_id  = !empty($_GET['vendor']) ? (int)$_GET['vendor'] : null;
		$status_f   = isset($_GET['status'])  ? $_GET['status']      : '';

		$authUser       = $this->Session->read('Auth.User');
		$userRole       = $authUser['role'] ?? '';
		$userLocationId = $authUser['location_ids'] ?? 0;

		$where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0
					AND ipo.created BETWEEN '$startDT' AND '$endDT'";
		if ($store_id)  $where .= " AND ipo.location_id = $store_id";
		elseif ($userRole !== 'admin' && !empty($userLocationId)) $where .= " AND ipo.location_id IN ($userLocationId)";
		if ($vendor_id) $where .= " AND ipo.vendor_id = $vendor_id";
		if ($status_f !== '') $where .= " AND ipo.status = " . (int)$status_f;

		$statusLabels = [1 => 'Submitted', 2 => 'Approved', 3 => 'Processed', 4 => 'Stocked In'];

		// Fetch PO-level summary
		$rows = $this->Inventory_purchase_order->query("
			SELECT ipo.p_o_id, ipo.created AS po_date, ipo.location_name AS store,
				ipo.vendor_name AS vendor, ipo.status,
				COUNT(ipoi.id) AS item_count, SUM(ipoi.sku_quantity) AS qty_total,
				SUM(ipoi.stockin_quantity) AS stockin_qty_total,
				SUM(ipoi.sku_price * ipoi.sku_quantity) AS gross,
				SUM(COALESCE(ipoi.sku_discount_value,0)) AS discount,
				SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
				SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
				SUM(COALESCE(ipoi.tcs_amount,0)) AS tcs,
				SUM(ipoi.sku_amount) AS total,
				SUM(ipoi.approved_amount) AS approved_amt,
				SUM(COALESCE(ipoi.processed_amount,0)) AS processed_amt,
				SUM(COALESCE(ipoi.stockin_amount,0)) AS stockin_amt
			FROM inventory_purchase_order ipo
			LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id AND ipoi.status != 0
			$where GROUP BY ipo.p_o_id ORDER BY ipo.id DESC
		");

		// Collect all PO IDs to fetch item lines in one query
		$poIds = [];
		foreach ($rows as $r) {
			$poIds[] = (int)$r['ipo']['p_o_id'];
		}

		// Fetch all item lines for these POs in one shot
		$itemsMap = [];
		if (!empty($poIds)) {
			$inList   = implode(',', $poIds);
			$itemRows = $this->Inventory_purchase_order->query("
				SELECT
					ipoi.p_o_id,
					ipoi.sku_name                                                                     AS item_name,
					ipoi.sku_quantity                                                                  AS qty,
					ipoi.stockin_quantity                                                             AS stockin_qty,
					(ipoi.sku_price * ipoi.sku_quantity)                                              AS gross,
					COALESCE(ipoi.sku_discount_value, 0)                                              AS discount,
					(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value, 0))       AS base,
					COALESCE(ipoi.sku_total_tax_value, 0)                                             AS tax,
					COALESCE(ipoi.tcs_amount, 0)                                                      AS tcs,
					ipoi.sku_amount                                                                    AS total,
					ipoi.approved_amount                                                               AS approved_amt,
					ipoi.processed_amount                                                              AS processed_amt,
					ipoi.stockin_amount                                                                AS stockin_amt
				FROM inventory_purchase_order_items ipoi
				WHERE ipoi.p_o_id IN ($inList) AND ipoi.status != 0
				ORDER BY ipoi.p_o_id, ipoi.id ASC
			");

			foreach ($itemRows as $ir) {
				$poId = $ir['ipoi']['p_o_id'] ?? $ir[0]['p_o_id'] ?? null;
				if (!$poId) continue;
				$itemsMap[$poId][] = [
					'item_name'     => $ir['ipoi']['item_name']    ?? $ir[0]['item_name']    ?? '',
					'qty'           => $ir['ipoi']['qty']          ?? $ir[0]['qty']          ?? 0,
					'stockin_qty'   => $ir['ipoi']['stockin_qty']  ?? $ir[0]['stockin_qty']  ?? 0,
					'gross'         => $ir[0]['gross']             ?? 0,
					'discount'      => $ir[0]['discount']          ?? 0,
					'base'          => $ir[0]['base']              ?? 0,
					'tax'           => $ir[0]['tax']               ?? 0,
					'tcs'           => $ir[0]['tcs']               ?? 0,
					'total'         => $ir['ipoi']['total']        ?? $ir[0]['total']        ?? 0,
					'approved_amt'  => $ir['ipoi']['approved_amt'] ?? $ir[0]['approved_amt'] ?? 0,
					'processed_amt' => $ir['ipoi']['processed_amt']?? $ir[0]['processed_amt']?? 0,
					'stockin_amt'   => $ir['ipoi']['stockin_amt']  ?? $ir[0]['stockin_amt']  ?? 0,
				];
			}
		}

		header('Content-Type: text/csv');
		header('Content-Disposition: attachment; filename="testPO_Report_v2_' . $startdate . '_' . $enddate . '.csv"');
		$fp = fopen('php://output', 'w');

		// Header row
		fputcsv($fp, ['PO No','Date','Store','Vendor','Status','Items','Item Qty','Stockin Qty','Gross','Discount','Base','Tax','TCS','Total','Approved(incl tax)','Processed(incl tax)','StockedIn(incl tax)']);

		foreach ($rows as $r) {
			$poId = $r['ipo']['p_o_id'];

			// PO summary row
			fputcsv($fp, [
				$poId,
				$r['ipo']['po_date']  ?? '',
				$r['ipo']['store']    ?? '',
				$r['ipo']['vendor']   ?? '',
				$statusLabels[$r['ipo']['status'] ?? 0] ?? 'Unknown',
				$r[0]['item_count']   ?? 0,
				round($r[0]['qty_total']     ?? 0, 3),
				round($r[0]['stockin_qty_total']     ?? 0, 3),
				round($r[0]['gross']         ?? 0, 2),
				round($r[0]['discount']      ?? 0, 2),
				round($r[0]['base']          ?? 0, 2),
				round($r[0]['tax']           ?? 0, 2),
				round($r[0]['tcs']           ?? 0, 2),
				round($r[0]['total']         ?? 0, 2),
				round($r[0]['approved_amt']  ?? 0, 2),
				round($r[0]['processed_amt'] ?? 0, 2),
				round($r[0]['stockin_amt']   ?? 0, 2),
			]);

			// Item detail rows — indented with 5 empty leading columns
			foreach ($itemsMap[$poId] ?? [] as $item) {
				fputcsv($fp, [
					'',   // PO No
					'',   // Date
					'',   // Store
					'',   // Vendor
					'',   // Status
					$item['item_name'],
					round($item['qty'],          3),
					round($item['stockin_qty'],  3),
					round($item['gross'],        2),
					round($item['discount'],     2),
					round($item['base'],         2),
					round($item['tax'],          2),
					round($item['tcs'],          2),
					round($item['total'],        2),
					round($item['approved_amt'], 2),
					round($item['processed_amt'],2),
					round($item['stockin_amt'],  2),
				]);
			}
		}

		fclose($fp);
		exit;
	}
    /**
     * C2: Vendor Wise Purchase Report
    */  
    public function vendor_wise_purchase_report()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime(date('Y-m-01')));
        $endDate   = date('m/d/Y');
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            $dates = explode(" - ", $daterange);
            $startDate = date('m/d/Y', strtotime(trim($dates[0])));
            $endDate   = date('m/d/Y', strtotime(trim($dates[1])));
        }
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate   = date('Y-m-d', strtotime($endDate));
        $startDT   = $startdate . ' 00:00:00';
        $endDT     = $enddate   . ' 23:59:59';

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $store_id = !empty($this->request->data['Search']['store']) ? (int)$this->request->data['Search']['store'] : null;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin') $where .= " AND ipo.location_id IN ($userLocationId)";

        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipo.vendor_id,
                ipo.vendor_name AS vendor,
                COUNT(DISTINCT ipo.p_o_id)    AS po_count,
                COUNT(DISTINCT ipoi.sku_id)   AS item_count,
                SUM(ipoi.sku_quantity)         AS qty,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0))  AS tax,
                SUM(ipoi.sku_amount)           AS total,
                SUM(CASE WHEN isku.expense_type='CAPEX' THEN ipoi.sku_amount ELSE 0 END) AS capex_total,
                SUM(CASE WHEN isku.expense_type='OPEX'  THEN ipoi.sku_amount ELSE 0 END) AS opex_total,
                SUM(CASE WHEN isku.expense_type NOT IN ('CAPEX','OPEX') THEN ipoi.sku_amount ELSE 0 END) AS unclassified_total
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
            $where
            GROUP BY ipo.vendor_id, ipo.vendor_name
            ORDER BY total DESC
        ");

        $vendorData = [];
        foreach ($rows as $r) {
            $vendorData[] = [
                'vendor_id'    => $r['ipo']['vendor_id']          ?? $r[0]['vendor_id']       ?? 0,
                'vendor'       => $r['ipo']['vendor']             ?? '',
                'po_count'     => $r[0]['po_count']               ?? 0,
                'item_count'   => $r[0]['item_count']             ?? 0,
                'qty'          => $r[0]['qty']                    ?? 0,
                'base'         => $r[0]['base']                   ?? 0,
                'tax'          => $r[0]['tax']                    ?? 0,
                'total'        => $r[0]['total']                  ?? 0,
                'capex_total'  => $r[0]['capex_total']            ?? 0,
                'opex_total'   => $r[0]['opex_total']             ?? 0,
                'unclassified' => $r[0]['unclassified_total']     ?? 0,
            ];
        }

        $conditions = ['status' => 1];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $conditions['id IN'] = array_map('trim', explode(',', $userLocationId));
        }
        $stores = $this->Location->find('all', ['conditions' => $conditions]);

        $this->set('startdate', $startDate . ' - ' . $endDate);
        $this->set(compact('stores', 'vendorData'));
    }
    
    public function vendor_wise_purchase_items()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->response->body(json_encode(['error' => 'Unauthorized']));
        }
        $this->autoRender = false;
        $this->response->type('application/json');

        $vendor_id = (int)($this->request->query('vendor_id') ?? 0);
        $startDT   = trim($this->request->query('start') ?? '');
        $endDT     = trim($this->request->query('end')   ?? '');
        $store_id  = (int)($this->request->query('store_id') ?? 0);

        if (!$vendor_id || !$startDT || !$endDT) {
            return $this->response->body(json_encode(['error' => 'Invalid parameters']));
        }
        
        $startdate = date('Y-m-d', strtotime($startDT));
        $enddate   = date('Y-m-d', strtotime($endDT));
        $startDT   = $startdate . ' 00:00:00';
        $endDT     = $enddate   . ' 23:59:59';

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.vendor_id = $vendor_id
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin') $where .= " AND ipo.location_id IN ($userLocationId)";

        
        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipoi.sku_id,
                ipoi.sku_name,
                SUM(ipoi.sku_quantity)                                                              AS qty,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value, 0))     AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value, 0))                                          AS tax,
                SUM(ipoi.sku_amount)                                                                AS total,
                SUM(CASE WHEN isku.expense_type = 'CAPEX' THEN ipoi.sku_amount ELSE 0 END)         AS capex_total,
                SUM(CASE WHEN isku.expense_type = 'OPEX'  THEN ipoi.sku_amount ELSE 0 END)         AS opex_total,
                SUM(CASE WHEN isku.expense_type NOT IN ('CAPEX','OPEX') THEN ipoi.sku_amount ELSE 0 END) AS unclassified_total
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
            $where
            GROUP BY ipoi.sku_id, ipoi.sku_name
            ORDER BY total DESC
        ");

        $result = [];
        foreach ($rows as $row) {
            // CakePHP puts real table columns under model alias key,
            // computed/aggregated columns under [0]
            // sku_id and sku_name are real columns on ipoi table → ['ipoi']
            // All SUM/CASE results → [0]
            $item_name = $row['ipoi']['sku_name'] ?? $row[0]['sku_name'] ?? '';

            // Fallback: if both empty, try the raw key CakePHP sometimes uses
            if ($item_name === '') {
                $item_name = $row['Inventory_purchase_order_items']['sku_name'] ?? '';
            }

            $result[] = [
                'item_name'    => $item_name,
                'qty'          => $row[0]['qty']               ?? 0,
                'base'         => $row[0]['base']              ?? 0,
                'tax'          => $row[0]['tax']               ?? 0,
                'total'        => $row[0]['total']             ?? 0,
                'capex_total'  => $row[0]['capex_total']       ?? 0,
                'opex_total'   => $row[0]['opex_total']        ?? 0,
                'unclassified' => $row[0]['unclassified_total'] ?? 0,
            ];
        }

        // ── Debug: if result empty, return raw first row so you can see actual keys ──
        if (empty($result)) {
            $raw = !empty($rows) ? $rows[0] : [];
            return $this->response->body(json_encode([
                'items' => [],
                'debug_raw_first_row' => $raw,
                'debug_row_count' => count($rows)
            ]));
        }

        return $this->response->body(json_encode(['items' => $result]));
    }

    public function vendor_wise_purchase_export()
    {
        $this->autoRender = false;
        $date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
        $dates      = explode(" - ", $date_range);
        $startdate  = date('Y-m-d', strtotime(trim($dates[0])));
        $enddate    = date('Y-m-d', strtotime(trim($dates[1])));
        $startDT    = $startdate . ' 00:00:00';
        $endDT      = $enddate   . ' 23:59:59';
        $store_id   = !empty($_GET['store']) ? (int)$_GET['store'] : null;

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin' && !empty($userLocationId)) $where .= " AND ipo.location_id IN ($userLocationId)";

        // ── Vendor-level summary (same as screen query) ──
        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipo.vendor_id,
                ipo.vendor_name AS vendor,
                COUNT(DISTINCT ipo.p_o_id)    AS po_count,
                COUNT(DISTINCT ipoi.sku_id)   AS item_count,
                SUM(ipoi.sku_quantity)         AS qty,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0))  AS tax,
                SUM(ipoi.sku_amount)           AS total,
                SUM(CASE WHEN isku.expense_type='CAPEX' THEN ipoi.sku_amount ELSE 0 END) AS capex_total,
                SUM(CASE WHEN isku.expense_type='OPEX'  THEN ipoi.sku_amount ELSE 0 END) AS opex_total,
                SUM(CASE WHEN isku.expense_type NOT IN ('CAPEX','OPEX') THEN ipoi.sku_amount ELSE 0 END) AS unclassified_total
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
            $where
            GROUP BY ipo.vendor_id, ipo.vendor_name
            ORDER BY total DESC
        ");

        // ── Collect vendor IDs to fetch item lines in one query ──
        $vendorIds = [];
        foreach ($rows as $r) {
            $vid = $r['ipo']['vendor_id'] ?? $r[0]['vendor_id'] ?? null;
            if ($vid) $vendorIds[] = (int)$vid;
        }

        // ── Item lines grouped by vendor_id + sku (same logic as AJAX action) ──
        $itemsMap = [];
        if (!empty($vendorIds)) {
            $inList   = implode(',', array_unique($vendorIds));
            $itemRows = $this->Inventory_purchase_order->query("
                SELECT
                    ipo.vendor_id,
                    ipoi.sku_id,
                    ipoi.sku_name,
                    SUM(ipoi.sku_quantity)                                                              AS qty,
                    SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value, 0))     AS base,
                    SUM(COALESCE(ipoi.sku_total_tax_value, 0))                                          AS tax,
                    SUM(ipoi.sku_amount)                                                                AS total,
                    SUM(CASE WHEN isku.expense_type='CAPEX' THEN ipoi.sku_amount ELSE 0 END)           AS capex_total,
                    SUM(CASE WHEN isku.expense_type='OPEX'  THEN ipoi.sku_amount ELSE 0 END)           AS opex_total,
                    SUM(CASE WHEN isku.expense_type NOT IN ('CAPEX','OPEX') THEN ipoi.sku_amount ELSE 0 END) AS unclassified_total
                FROM inventory_purchase_order ipo
                LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
                LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
                WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.vendor_id IN ($inList)
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'
                GROUP BY ipo.vendor_id, ipoi.sku_id, ipoi.sku_name
                ORDER BY ipo.vendor_id, total DESC
            ");

            foreach ($itemRows as $ir) {
                $vid = $ir['ipo']['vendor_id'] ?? $ir[0]['vendor_id'] ?? null;
                if (!$vid) continue;
                $itemsMap[$vid][] = [
                    'item_name'    => $ir['ipoi']['sku_name']          ?? $ir[0]['sku_name']          ?? '',
                    'qty'          => $ir[0]['qty']                    ?? 0,
                    'base'         => $ir[0]['base']                   ?? 0,
                    'tax'          => $ir[0]['tax']                    ?? 0,
                    'total'        => $ir[0]['total']                  ?? 0,
                    'capex_total'  => $ir[0]['capex_total']            ?? 0,
                    'opex_total'   => $ir[0]['opex_total']             ?? 0,
                    'unclassified' => $ir[0]['unclassified_total']     ?? 0,
                ];
            }
        }

        // ── Output CSV ──
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="Vendor_Wise_Purchase_' . $startdate . '_' . $enddate . '.csv"');
        $fp = fopen('php://output', 'w');

        // Header row — columns match both vendor summary + item detail rows
        fputcsv($fp, ['Vendor','POs','Items','Qty','Base','Tax','Total','CAPEX','OPEX','Unclassified']);

        foreach ($rows as $r) {
            $vid = $r['ipo']['vendor_id'] ?? $r[0]['vendor_id'] ?? null;

            // ── Vendor summary row ──
            fputcsv($fp, [
                $r['ipo']['vendor']               ?? '',
                $r[0]['po_count']                 ?? 0,
                '',                                        // Item Name blank on summary row
                round($r[0]['qty']                ?? 0, 3),
                round($r[0]['base']               ?? 0, 2),
                round($r[0]['tax']                ?? 0, 2),
                round($r[0]['total']              ?? 0, 2),
                round($r[0]['capex_total']        ?? 0, 2),
                round($r[0]['opex_total']         ?? 0, 2),
                round($r[0]['unclassified_total'] ?? 0, 2),
            ]);

            // ── Item detail rows — vendor + POs blank, indented under summary ──
            foreach ($itemsMap[$vid] ?? [] as $item) {
                fputcsv($fp, [
                    '',   // Vendor
                    '',   // # POs
                    $item['item_name'],
                    round($item['qty'],          3),
                    round($item['base'],         2),
                    round($item['tax'],          2),
                    round($item['total'],        2),
                    round($item['capex_total'],  2),
                    round($item['opex_total'],   2),
                    round($item['unclassified'], 2),
                ]);
            }
        }

        fclose($fp);
        exit;
    }
    
    /**
     * C3: Item Wise Purchase Report
    */
    
    public function item_wise_purchase_report()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->layout = "users";
        $startDate = date('m/d/Y', strtotime(date('Y-m-01')));
        $endDate   = date('m/d/Y');
        if ($this->request->is(['post', 'put'])) {
            $daterange = $this->request->data['daterange'] ?? '';
            $dates = explode(" - ", $daterange);
            $startDate = date('m/d/Y', strtotime(trim($dates[0])));
            $endDate   = date('m/d/Y', strtotime(trim($dates[1])));
        }
        $startdate = date('Y-m-d', strtotime($startDate));
        $enddate   = date('Y-m-d', strtotime($endDate));
        $startDT   = $startdate . ' 00:00:00';
        $endDT     = $enddate   . ' 23:59:59';

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $store_id = !empty($this->request->data['Search']['store']) ? (int)$this->request->data['Search']['store'] : null;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin') $where .= " AND ipo.location_id IN ($userLocationId)";

        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipoi.sku_id,
                ipoi.sku_name AS sku,
                ipoi.sku_unit_name AS unit,
                isku.expense_type,
                SUM(ipoi.sku_quantity) AS qty,
                ROUND(SUM(ipoi.sku_price * ipoi.sku_quantity) / NULLIF(SUM(ipoi.sku_quantity),0), 4) AS weighted_avg_rate,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
                SUM(ipoi.sku_amount) AS total,
                COUNT(DISTINCT ipo.vendor_id) AS vendor_count
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
            $where
            GROUP BY ipoi.sku_id, ipoi.sku_name, ipoi.sku_unit_name, isku.expense_type
            ORDER BY ipoi.sku_name ASC
        ");

        $itemData = [];
        foreach ($rows as $r) {
            $itemData[] = [
                'sku_id'        => $r['ipoi']['sku_id']        ?? $r[0]['sku_id']           ?? 0,
                'sku'           => $r['ipoi']['sku']           ?? $r[0]['sku']              ?? '',
                'unit'          => $r['ipoi']['unit']          ?? $r[0]['unit']             ?? '',
                'expense_type'  => $r['isku']['expense_type']  ?? $r[0]['expense_type']     ?? 'UNCLASSIFIED',
                'qty'           => $r[0]['qty']                ?? 0,
                'weighted_avg'  => $r[0]['weighted_avg_rate']  ?? 0,
                'base'          => $r[0]['base']               ?? 0,
                'tax'           => $r[0]['tax']                ?? 0,
                'total'         => $r[0]['total']              ?? 0,
                'vendor_count'  => $r[0]['vendor_count']       ?? 0,
            ];
        }

        $conditions = ['status' => 1];
        if ($userRole !== 'admin' && !empty($userLocationId)) {
            $conditions['id IN'] = array_map('trim', explode(',', $userLocationId));
        }
        $stores = $this->Location->find('all', ['conditions' => $conditions]);

        $this->set('startdate', $startDate . ' - ' . $endDate);
        $this->set(compact('stores', 'itemData'));
    }

    /**
     * AJAX: Return vendor breakdown for a single SKU
     */
    public function item_wise_purchase_vendors()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->response->body(json_encode(['error' => 'Unauthorized']));
        }
        $this->autoRender = false;
        $this->response->type('application/json');

        $sku_id   = (int)($this->request->query('sku_id')   ?? 0);
        $startDT  = trim($this->request->query('start')     ?? '');
        $endDT    = trim($this->request->query('end')       ?? '');
        $store_id = (int)($this->request->query('store_id') ?? 0);

        if (!$sku_id || !$startDT || !$endDT) {
            return $this->response->body(json_encode(['error' => 'Invalid parameters']));
        }
        
        
        $startdate = date('Y-m-d', strtotime($startDT));
        $enddate   = date('Y-m-d', strtotime($endDT));
        $startDT   = $startdate . ' 00:00:00';
        $endDT     = $enddate   . ' 23:59:59';

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipoi.sku_id = $sku_id
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin') $where .= " AND ipo.location_id IN ($userLocationId)";

        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipo.vendor_id,
                ipo.vendor_name AS vendor,
                COUNT(DISTINCT ipo.p_o_id) AS po_count,
                SUM(ipoi.sku_quantity) AS qty,
                ROUND(SUM(ipoi.sku_price * ipoi.sku_quantity) / NULLIF(SUM(ipoi.sku_quantity),0), 4) AS weighted_avg_rate,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
                SUM(ipoi.sku_amount) AS total
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            $where
            GROUP BY ipo.vendor_id, ipo.vendor_name
            ORDER BY total DESC
        ");

        $result = [];
        foreach ($rows as $row) {
            $vendor = $row['ipo']['vendor'] ?? $row[0]['vendor'] ?? '';
            if ($vendor === '') {
                $vendor = $row['Inventory_purchase_order']['vendor'] ?? '';
            }
            $result[] = [
                'vendor'       => $vendor,
                'po_count'     => $row[0]['po_count']       ?? 0,
                'qty'          => $row[0]['qty']             ?? 0,
                'weighted_avg' => $row[0]['weighted_avg_rate'] ?? 0,
                'base'         => $row[0]['base']            ?? 0,
                'tax'          => $row[0]['tax']             ?? 0,
                'total'        => $row[0]['total']           ?? 0,
            ];
        }

        if (empty($result)) {
            $raw = !empty($rows) ? $rows[0] : [];
            return $this->response->body(json_encode([
                'items' => [],
                'debug_raw_first_row' => $raw,
                'debug_row_count'     => count($rows)
            ]));
        }

        return $this->response->body(json_encode(['items' => $result]));
    }
    
    public function item_wise_purchase_export()
    {
        $this->autoRender = false;
        $date_range = $_GET['sdate'] ?? date('m/d/Y') . ' - ' . date('m/d/Y');
        $dates      = explode(" - ", $date_range);
        $startdate  = date('Y-m-d', strtotime(trim($dates[0])));
        $enddate    = date('Y-m-d', strtotime(trim($dates[1])));
        $startDT    = $startdate . ' 00:00:00';
        $endDT      = $enddate   . ' 23:59:59';
        $store_id   = !empty($_GET['store']) ? (int)$_GET['store'] : null;

        $authUser       = $this->Session->read('Auth.User');
        $userRole       = $authUser['role'] ?? '';
        $userLocationId = $authUser['location_ids'] ?? 0;

        $where = "WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'";
        if ($store_id) $where .= " AND ipo.location_id = $store_id";
        elseif ($userRole !== 'admin' && !empty($userLocationId)) $where .= " AND ipo.location_id IN ($userLocationId)";

        // ── SKU-level summary (same as screen query) ──
        $rows = $this->Inventory_purchase_order->query("
            SELECT
                ipoi.sku_id,
                ipoi.sku_name AS sku,
                ipoi.sku_unit_name AS unit,
                isku.expense_type,
                SUM(ipoi.sku_quantity) AS qty,
                ROUND(SUM(ipoi.sku_price * ipoi.sku_quantity) / NULLIF(SUM(ipoi.sku_quantity),0), 4) AS weighted_avg_rate,
                SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
                SUM(ipoi.sku_amount) AS total,
                COUNT(DISTINCT ipo.vendor_id) AS vendor_count
            FROM inventory_purchase_order ipo
            LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
            LEFT JOIN inventory_skus isku ON isku.id = ipoi.sku_id
            $where
            GROUP BY ipoi.sku_id, ipoi.sku_name, ipoi.sku_unit_name, isku.expense_type
            ORDER BY ipoi.sku_name ASC
        ");

        // ── Collect SKU IDs to fetch vendor lines in one query ──
        $skuIds = [];
        foreach ($rows as $r) {
            $sid = $r['ipoi']['sku_id'] ?? $r[0]['sku_id'] ?? null;
            if ($sid) $skuIds[] = (int)$sid;
        }

        // ── Vendor lines grouped by sku_id + vendor (same logic as AJAX action) ──
        $vendorsMap = [];
        if (!empty($skuIds)) {
            $inList   = implode(',', array_unique($skuIds));
            $vendorRows = $this->Inventory_purchase_order->query("
                SELECT
                    ipoi.sku_id,
                    ipo.vendor_id,
                    ipo.vendor_name AS vendor,
                    COUNT(DISTINCT ipo.p_o_id) AS po_count,
                    SUM(ipoi.sku_quantity) AS qty,
                    ROUND(SUM(ipoi.sku_price * ipoi.sku_quantity) / NULLIF(SUM(ipoi.sku_quantity),0), 4) AS weighted_avg_rate,
                    SUM(ipoi.sku_price * ipoi.sku_quantity - COALESCE(ipoi.sku_discount_value,0)) AS base,
                    SUM(COALESCE(ipoi.sku_total_tax_value,0)) AS tax,
                    SUM(ipoi.sku_amount) AS total
                FROM inventory_purchase_order ipo
                LEFT JOIN inventory_purchase_order_items ipoi ON ipo.p_o_id = ipoi.p_o_id
                WHERE ipo.direct_purchase = 0 AND ipo.status != 0 AND ipoi.status != 0
                    AND ipoi.sku_id IN ($inList)
                    AND ipo.created BETWEEN '$startDT' AND '$endDT'
                GROUP BY ipoi.sku_id, ipo.vendor_id, ipo.vendor_name
                ORDER BY ipoi.sku_id, total DESC
            ");

            foreach ($vendorRows as $vr) {
                $sid = $vr['ipoi']['sku_id'] ?? $vr[0]['sku_id'] ?? null;
                if (!$sid) continue;
                $vendorsMap[$sid][] = [
                    'vendor'       => $vr['ipo']['vendor']       ?? $vr[0]['vendor']            ?? '',
                    'po_count'     => $vr[0]['po_count']         ?? 0,
                    'qty'          => $vr[0]['qty']              ?? 0,
                    'weighted_avg' => $vr[0]['weighted_avg_rate'] ?? 0,
                    'base'         => $vr[0]['base']             ?? 0,
                    'tax'          => $vr[0]['tax']              ?? 0,
                    'total'        => $vr[0]['total']            ?? 0,
                ];
            }
        }

        // ── Output CSV ──
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="Item_Wise_Purchase_' . $startdate . '_' . $enddate . '.csv"');
        $fp = fopen('php://output', 'w');

        // Columns cover both SKU summary rows and vendor detail rows
        fputcsv($fp, ['SKU','Unit','Type','# Vendors','Vendor','# POs','Qty','Wtd Avg Rate','Base','Tax','Total']);

        foreach ($rows as $r) {
            $sid = $r['ipoi']['sku_id'] ?? $r[0]['sku_id'] ?? null;

            // ── SKU summary row ──
            fputcsv($fp, [
                $r['ipoi']['sku']              ?? '',
                $r['ipoi']['unit']             ?? '',
                $r['isku']['expense_type']     ?? 'UNCLASSIFIED',
                $r[0]['vendor_count']          ?? 0,
                '',                                        // Vendor blank on summary row
                '',                                        // # POs blank on summary row
                round($r[0]['qty']               ?? 0, 3),
                round($r[0]['weighted_avg_rate'] ?? 0, 4),
                round($r[0]['base']              ?? 0, 2),
                round($r[0]['tax']               ?? 0, 2),
                round($r[0]['total']             ?? 0, 2),
            ]);

            // ── Vendor detail rows — SKU/Unit/Type/# Vendors blank, indented under summary ──
            foreach ($vendorsMap[$sid] ?? [] as $v) {
                fputcsv($fp, [
                    '',   // SKU
                    '',   // Unit
                    '',   // Type
                    '',   // # Vendors
                    $v['vendor'],
                    $v['po_count'],
                    round($v['qty'],          3),
                    round($v['weighted_avg'], 4),
                    round($v['base'],         2),
                    round($v['tax'],          2),
                    round($v['total'],        2),
                ]);
            }
        }

        fclose($fp);
        exit;
    }
    
    /**
     * C5: Purchase Classification (CAPEX/OPEX)
     * UI to search SKU and set expense_type; bulk by category.
     */
    public function purchase_classification()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }
        $this->layout = "users";

        $authUser = $this->Session->read('Auth.User');
        if (!in_array($authUser['role'] ?? '', ['admin', 'manager'])) {
            $this->Session->setFlash('Access denied.', 'default', ['class' => 'alert alert-danger']);
            return $this->redirect(['action' => 'po_list']);
        }

        // Handle save single SKU
        if ($this->request->is('post') && !empty($this->request->data['sku_id'])) {
            $sku_id      = (int)$this->request->data['sku_id'];
            $etype       = in_array($this->request->data['expense_type'], ['CAPEX','OPEX','UNCLASSIFIED'])
                           ? $this->request->data['expense_type'] : 'UNCLASSIFIED';
            $this->Inventory_sku->updateAll(
                ['Inventory_sku.expense_type' => "'$etype'"],
                ['Inventory_sku.id' => $sku_id]
            );
            $this->Session->setFlash("SKU #$sku_id classified as $etype.", 'default', ['class' => 'alert alert-success']);
        }

        // Handle bulk-by-category
        if ($this->request->is('post') && !empty($this->request->data['bulk_cat_id'])) {
            $cat_id = (int)$this->request->data['bulk_cat_id'];
            $etype  = in_array($this->request->data['bulk_expense_type'], ['CAPEX','OPEX','UNCLASSIFIED'])
                      ? $this->request->data['bulk_expense_type'] : 'UNCLASSIFIED';
            $this->Inventory_sku->updateAll(
                ['Inventory_sku.expense_type' => "'$etype'"],
                ['Inventory_sku.cat_id' => $cat_id]
            );
            $this->Session->setFlash("All SKUs in category #$cat_id set to $etype.", 'default', ['class' => 'alert alert-success']);
        }

        $skus = $this->Inventory_sku->find('all', [
            'conditions' => ['Inventory_sku.status' => 1],
            'fields'     => ['Inventory_sku.id','Inventory_sku.name','Inventory_sku.cat_name','Inventory_sku.expense_type'],
            'order'      => ['Inventory_sku.name ASC'],
        ]);

        $categories = $this->Inventory_category->find('list', [
            'conditions' => ['Inventory_category.status' => 1],
            'fields'     => ['Inventory_category.id','Inventory_category.name'],
        ]);

        $this->set(compact('skus', 'categories'));
    }

    public function export_semifinished_recipe_costing()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        // ── Resolve semifinished list ─────────────────────────────
        $exportAll  = !empty($_POST['export_all']) && $_POST['export_all'] == '1';
        $idsParam   = isset($_POST['semifinished_ids']) ? trim($_POST['semifinished_ids']) : '';
        $ids = [];

        if ($exportAll || $idsParam === '') {
            $rows = $this->Inventory_semifinished->query(
                "SELECT id FROM inventory_semifinished WHERE status = 1 ORDER BY id ASC"
            );
            foreach ($rows as $r) {
                $ids[] = $r['inventory_semifinished']['id'];
            }
        } else {
            foreach (explode(',', $idsParam) as $v) {
                $v = intval(trim($v));
                if ($v > 0) $ids[] = $v;
            }
        }

        if (empty($ids)) {
            $this->Flash->error('No records selected.');
            return $this->redirect(['action' => 'semifinished_list']);
        }

        // ── Load data ─────────────────────────────────────────────
        $items = [];

        foreach ($ids as $id) {

            $row = $this->Inventory_semifinished->query(
                "SELECT id, name, price FROM inventory_semifinished WHERE id = $id LIMIT 1"
            );
            if (empty($row)) continue;

            $name  = $row[0]['inventory_semifinished']['name'];
            $price = floatval($row[0]['inventory_semifinished']['price']);

            // SKU
            $skuRows = $this->Inventory_linking->query(
                "SELECT il.component_name,
                        il.component_unit_name AS uom,
                        il.conversion_quantity AS req_qty,
                        COALESCE(sk.consumption_unit_price, 0) AS unit_cost,
                        COALESCE(NULLIF(sk.consumption_factor,0),1) AS per_unit,
                        ROUND(il.conversion_quantity * COALESCE(sk.consumption_unit_price, 0), 4) AS line_cost,
                        'Sku' AS comp_type
                 FROM inventory_linking il
                 LEFT JOIN inventory_skus sk ON sk.id = il.component_id
                 WHERE il.parent_id = $id
                 AND il.parent_type = 'Semifinished'
                 AND il.component_type = 'Sku'
                 AND il.status = 1"
            );

            // Nested Semifinished
            $semiRows = $this->Inventory_linking->query(
                "SELECT il.component_name,
                        il.component_unit_name AS uom,
                        il.conversion_quantity AS req_qty,
                        COALESCE(vsf.unit_cost,0) AS unit_cost,
                        1 AS per_unit,
                        ROUND(il.conversion_quantity * COALESCE(vsf.unit_cost,0), 4) AS line_cost,
                        'Semifinished' AS comp_type
                 FROM inventory_linking il
                 LEFT JOIN v_semifinished_recipe_cost vsf ON vsf.id = il.component_id
                 WHERE il.parent_id = $id
                 AND il.parent_type = 'Semifinished'
                 AND il.component_type = 'Semifinished'
                 AND il.status = 1"
            );

            $ingredients = [];

            foreach ($semiRows as $r) {
                $merged = array_merge($r['il'] ?? [], $r[0] ?? []);
                $ingredients[] = array_merge($merged, ['comp_type' => 'Semifinished']);
            }

            foreach ($skuRows as $r) {
                $merged = array_merge($r['il'] ?? [], $r[0] ?? []);
                $ingredients[] = array_merge($merged, ['comp_type' => 'Sku']);
            }

            $totalCost = array_sum(array_column($ingredients, 'line_cost'));

            $items[] = [
                'id' => $id,
                'name' => $name,
                'price' => $price,
                'ingredients' => $ingredients,
                'total_cost' => $totalCost,
            ];
        }

        // ── Excel (same as your product logic) ───────────────────
        App::import('Vendor', 'PHPExcel/PHPExcel');
        $xls = new PHPExcel();
        $sheet = $xls->getActiveSheet();
        $sheet->setTitle('SemiFinished Costing');

        $semiFill = [
            'type' => PHPExcel_Style_Fill::FILL_SOLID,
            'startcolor' => ['rgb' => 'FFF2CC'] // light yellow
        ];

        $headers = ['SR','NAME','INGREDIENT','UOM','REQ QTY','UNIT COST','PER UNIT','COST PRICE','SELLING PRICE','MARGIN'];

        $col = 'A';
        foreach ($headers as $h) {
            $sheet->setCellValue($col.'1', $h);
            $col++;
        }

        $row = 2;
        $sr = 1;

        foreach ($items as $item) {

            $sheet->setCellValue("A$row", $item['id']);
            $sheet->setCellValue("B$row", $item['name']);
            $sheet->setCellValue("H$row", $item['total_cost']);
            $sheet->setCellValue("I$row", $item['price']);
            $sheet->setCellValue("J$row", $item['price'] - $item['total_cost']);
            $row++;

            foreach ($item['ingredients'] as $ing) {

                $isSemi = ($ing['comp_type'] === 'Semifinished'); // ✅ detect semi

                $sheet->setCellValue("C$row", $ing['component_name']);
                $sheet->setCellValue("D$row", $ing['uom']);
                $sheet->setCellValue("E$row", $ing['req_qty']);
                $sheet->setCellValue("F$row", round($ing['unit_cost'], 2));
                $sheet->setCellValue("G$row", $ing['per_unit']);
                $sheet->setCellValue("H$row", $ing['line_cost']);

                 // ✅ APPLY YELLOW COLOR IF SEMI
                if ($isSemi) {
                    $sheet->getStyle("A$row:J$row")->applyFromArray([
                        'fill' => $semiFill,
                        'font' => ['bold' => true] // optional
                    ]);
                }
                $row++;
            }

            $sheet->setCellValue("G$row", 'TOTAL');
            $sheet->setCellValue("H$row", $item['total_cost']);
            $row += 2;
        }

        $filename = 'SemiFinished_Costing_' . date('Ymd_His') . '.xls';

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="'.$filename.'"');
        header('Cache-Control: max-age=0');

        PHPExcel_IOFactory::createWriter($xls, 'Excel5')->save('php://output');
        exit;
    }

    public function internal_indent_pdf()
    {
        if (!$this->Session->check('Auth.User.id')) {
            return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
        }

        $this->layout = false; // for print/pdf

        $id = (int)$_GET['id']; // secure

        $indents = $this->Inventory_internal_indent->find('all', [
            'conditions' => ['indent_id' => $id, 'status' => 1]
        ]);

        $items = $this->Inventory_internal_indent_items->find('all', [
            'conditions' => ['indent_id' => $id, 'status' => 1]
        ]);

        $location_id = $indents[0]['Inventory_internal_indent']['location_id'];

        $locationdetail = $this->Location->find('first', [
            'conditions' => ['Location.id' => $location_id]
        ]);

        $this->set(compact('indents', 'items','locationdetail'));
    }
	
	
	
	public function services()
	{
		if (!$this->Session->check('Auth.User.id')) {
			return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
		}
		
        $this->loadModel('Service');
		$this->layout = "users";

		$services = $this->Service->find('all', [
			'order' => ['Service.id' => 'DESC']
		]);

		$this->set(compact('services'));
	}


	/* ================= CREATE ================= */
	public function add_service()
	{
		if (!$this->Session->check('Auth.User.id')) {
			return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
		}

        $this->loadModel('Service');
		$this->layout = "users";
		if ($this->request->is('post')) {

			$this->Service->create();

			if ($this->Service->save($this->request->data)) {
                $this->Flash->success(__('Service has been saved.'));
                return $this->redirect(array('action' => 'services'));
			} else {
				$this->Session->setFlash('Error adding service');
			}
		}
	}

	/* ================= EDIT ================= */
	public function edit_service()
	{
		if (!$this->Session->check('Auth.User.id')) {
			return $this->redirect(['controller' => 'dashboard', 'action' => 'login']);
		}

        $this->loadModel('Service');
		$this->layout = "users";

		$id = $this->request->query('id');

		if (!$id) {
			return $this->redirect(['action' => 'services']);
		}

		$service = $this->Service->findById($id);

		if (!$service) {
			return $this->redirect(['action' => 'services']);
		}

		if ($this->request->is(['post', 'put'])) {

			$this->Service->id = $id;

			if ($this->Service->save($this->request->data)) {
                $this->Flash->success(__('Service updated'));
                return $this->redirect(array('action' => 'services'));
			} else {
				$this->Session->setFlash('Update failed');
			}
		}

		$this->request->data = $service;
	}

	/* ================= SOFT DELETE ================= */
	public function delete_service()
	{
		$this->autoRender = false; // VERY IMPORTANT

        $this->loadModel('Service');
		if ($this->request->is('post')) {

			$id = $this->request->data['_id'];

			if (!$id) {
				echo json_encode(['status' => false, 'msg' => 'No ID']);
				return;
			}

			$service = $this->Service->findById($id);

			if (!$service) {
				echo json_encode(['status' => false, 'msg' => 'Not found']);
				return;
			}

			$currentStatus = $service['Service']['status'];
			$newStatus = ($currentStatus == 1) ? 0 : 1;

			$this->Service->id = $id;

			if ($this->Service->saveField('status', $newStatus)) {
				echo json_encode(['status' => true]);
			} else {
				echo json_encode(['status' => false, 'msg' => 'Save failed']);
			}
		}
	}



}

