<?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 ApisController
 * @author aetherss
 */
class ApisController extends AppController {
    public function beforeFilter() {
        parent::beforeFilter();
        // Allow users to register and logout.
        $this->Auth->allow();
        $this->layout = false;
        $this->autoRender = false;
        error_reporting(0);
    }
    
    public function index()
    {
        echo "Welcome to PhyloPos";
    }
    // Global Use Private Functions 
     
    /************************* MOBILE APP APIS ******************************/
    public function login()
    {
        $username = $_REQUEST['username'];
        $password = $_REQUEST['password'];
        $device_id = $_REQUEST['device_id'];
        
        if(!isset($username)){
            $response['status']= false;
            $response['message']= "username missing..!";
            return json_encode($response);
        }
        if($password==''){
            $response['status']= false;
            $response['message']= "Password missing..!";
            return json_encode($response);
        }
        $password = AuthComponent::password($password);
        $response = array();
        
        $users = $this->User->find('first', array('conditions'=>array('User.username'=>$username,'User.password'=>$password,'User.role'=>'cashier','User.status'=>1)));
        if(!empty($users))
        {
            if(isset($device_id)){
                $id=$users['User']['id'];
                $this->User->query("UPDATE users SET device_id = '$device_id',sync=0,local_sync=0 WHERE id = $id");
            }
            
            if(isset($users['User']['username'])){
                $username=$users['User']['username'];
            }else{
                $username='';
            }
            if(isset($users['User']['name'])){
                $name=$users['User']['name'];
            }else{
                $name='';
            }
            if(isset($users['User']['mobile'])){
                $mobile=$users['User']['mobile'];
            }else{
                $mobile='';
            }
            $modules=modules;
            
            $flags = [];
            foreach ($modules as $module) {
                $flags[$module] = false;
            }
            
            $usermodules = $this->User_module->find('all', array('conditions'=>array('User_module.user_id'=>$users['User']['id'],'User_module.status'=>1)));
            if($usermodules){
                foreach($usermodules as $usermodule){
                    $moduleName = $usermodule['User_module']['name'];
                    // print_r($moduleName);exit;
                    if (array_key_exists($moduleName, $flags)) {
                        $flags[$moduleName] = true;
                    }
                }
            }
            $loc_id=0;
            $userlocations = $this->User_location->find('first', array('conditions'=>array('user_id'=>$users['User']['id'],'status'=>1,'billing_location'=>1)));
if($userlocations){
    $loc_id=$userlocations['User_location']['location_id'];
    $locations = $this->Location->find('first', array('conditions'=>array('Location.id'=>$loc_id,'Location.status'=>1)));

}else{
    $locations = $this->Location->find('first', array('conditions'=>array('Location.id'=>$users['User']['location_id'],'Location.status'=>1)));
}

            $datas['User_track']=array(
                'user_id'=>$users['User']['id'],
                'location_id'=>$users['User']['location_id'],
                'location_name'=>$users['User']['location_name'],
                'type'=>'login',
                'remarks'=>'login'
            );
            if(!$this->User_track->saveAll($datas['User_track']))
            {
                $response['track']= "Not Saved..!";
            }
            
            //print_r($locations['Location']['name']);exit;
            
            $response['status']= true;
            $response['message']= "Success..!";
            $response['id']= $users['User']['id'];
            $response['username']= $username;
            $response['name']= $name;
            $response['role']= $users['User']['role'];
            $response['can_settlement']= $users['User']['can_settlement'];
            $response['billprint_ip']= $users['User']['billprint_ip'];
            $response['mobile']= $mobile;
            $response['location_id']= $loc_id;
            $response['location_name']= $locations['Location']['name'] ?? '';
            $response['print_line1']= $locations['Location']['print_line1'] ?? '';
            $response['print_line2']= $locations['Location']['print_line2'] ?? '';
            $response['print_line3']= $locations['Location']['print_line3'] ?? '';
            $response['print_line4']= $locations['Location']['print_line4'] ?? '';
            $response['print_line5']= $locations['Location']['print_line5'] ?? '';
            $response['print_line6']= $locations['Location']['print_line6'] ?? '';
            $response['print_line7']= $locations['Location']['print_line7'] ?? '';
            $response['print_line8']= $locations['Location']['print_line8'] ?? '';
            $response['print_line9']= $locations['Location']['print_line9'] ?? '';
            $response['print_line10']= $locations['Location']['print_line10'] ?? '';
            $response['footer_msg']= $locations['Location']['footer_msg'] ?? '';
            $response['currency_symbol']= $locations['Location']['currency_symbol'] ?? '';
            $response['created']= $users['User']['created'];
            $response['track']= "Saved..!";
            
            foreach ($modules as $module) {
                $response[$module] = $flags[$module];
            }
            
            
        }
        else
        {
            $response['status']= false;
            $response['message']= "Failed..!";
        }
        return json_encode($response);
    }
     
    public function cardstatuscheck()
    {
        //$sendmessage= new UtilityController;
        
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);

        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card No Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found",
            );
            return json_encode($response);
        }else{
            if($card[Card]['name']){
                $name=$card['Card']['name'];
            }else{
                $name='';
            }
            $phone=$card['Card']['mobile'];
            $response['status']= true;
            $response['statusvalue']= $card[Card]['status'];
            $response['customername']= $name;
            $response['cardbalance']= $card[Card]['cardbalance'];
            $response['message']= "Card is diabled please contact to support.";
        }
        return json_encode($response);
    }
    
    public function generateotp()
    {
        $sendmessage= new UtilityController;
        
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);

        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card No Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found",
            );
            return json_encode($response);
        }else{
            $name=$card['Card']['name'];
            $phone=$card['Card']['mobile'];
            // $otp = mt_rand(1000, 9999);
            // print_r($otpp);
            $otp=1111;
            $this->Card->query("UPDATE cards SET otp = '$otp',sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            $message = "Hi $name, please use $otp to login to PhyloPay.";
//          $sendmessage->message($message,$phone);
            
            $response['status']= true;
            $response['message']= "Success..!";
            $response['otp']= $otp;
        }
        return json_encode($response);
    }
    
    public function cardaddbalance()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $amount = $_REQUEST['amount'];
        // $otp = $_REQUEST['otp'];
        $mode = $_REQUEST['mode'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($amount==''){
            $response =array(
                'status'=> false,
                'message'=> "Amount Missing",
            );
            return json_encode($response);
        }
        if($amount<1){
            $response =array(
                'status'=> false,
                'message'=> "Amount need to be greater than 0",
            );
            return json_encode($response);
        }
        // if($otp==''){
        //     $response =array(
        //         'status'=> false,
        //         'message'=> "Otp Missing",
        //     );
        //     return json_encode($response);
        // }
        if($mode==''){
            $response =array(
                'status'=> false,
                'message'=> "payment mode Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card Deactivated",
            );
            return json_encode($response);
        }else{
            // $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.otp'=>$otp,'Card.status'=>2)));
            // if(empty($card))
            // {
            //     $response =array(
            //         'status'=> false,
            //         'message'=> "Wrong OTP ",
            //     );
            //     return json_encode($response);
            // }
            $name=$card['Card']['name'];
            $mobile=$card['Card']['mobile'];
            $oldbal=$card['Card']['cardbalance'];
            $newbal=$oldbal+$amount;
            
            do {
                $txnid = '';
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existingOTP = $this->Cardtracking->find('first', array(
                    'conditions' => array(
                        'txnid' => $txnid
                    )
                ));
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $data['Cardtracking']=array(
                'cardnumber'=>$cardno,
                'cashierID'=>$cashierid,
                'txnid'=>$txnid,
                'cashierName'=>$cashiername,
                'customername'=>$name,
                'customerphone'=>$mobile,
                'purpose'=>'add',
                'oldbalance'=>$oldbal,
                'amount'=>$amount,
                'newbalance'=>$newbal,
                'type'=>1,
                'payment_mode'=>$mode
            );
          
            if($this->Cardtracking->saveAll($data['Cardtracking']))
            {
                $this->Card->query("UPDATE cards SET cardbalance = $newbal,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            
                $response= array('status'=> true,
                    'message'=> "Balance Added successfully",
                    'cardno'=>$cardno,
                    'balance'=>$newbal
                );
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "failed",
                );
            }
        }
        return json_encode($response);
    }
    
    public function cardwithdrawalbalance()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $amount = $_REQUEST['amount'];
        $otp = $_REQUEST['otp'];
        $mode = $_REQUEST['mode'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($amount==''){
            $response =array(
                'status'=> false,
                'message'=> "Amount Missing",
            );
            return json_encode($response);
        }
        
        if($mode==''){
            $response =array(
                'status'=> false,
                'message'=> "payment mode Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card Deactivated",
            );
            return json_encode($response);
        }else{
            $pinreq=$card['Card']['pin_required'];
            if($pinreq){
                if($otp==''){
                    $response =array(
                        'status'=> false,
                        'message'=> "PIN Missing",
                    );
                    return json_encode($response);
                }
                $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.pin'=>$otp,'Card.status'=>2)));
                if(empty($card))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Wrong PIN ",
                    );
                    return json_encode($response);
                }
            }
            $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.cardbalance >= '=>$amount)));
            if(empty($card))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdrawal Amount not exist in card ",
                );
                return json_encode($response);
            }
            
            $today = date("Y-m-d H:i:s");
            $currentDate = new DateTime($today);
            $newdate = $currentDate->modify('-2 minute')->format('Y-m-d H:i:s');

            $cardtrackingchk = $this->Cardtracking->query("SELECT * FROM cardtracking where cardnumber='$cardno' and amount='$amount' and created between '$newdate' and '$today' and type=2");
            if(!empty($cardtrackingchk))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdraw blocked for 2 minutes",
                );
                return json_encode($response);
            }
            
            $name=$card['Card']['name'];
            $mobile=$card['Card']['mobile'];
            $oldbal=$card['Card']['cardbalance'];
            $newbal=$oldbal-$amount;
            
            do {
                $txnid = '';
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existingOTP = $this->Cardtracking->find('first', array(
                    'conditions' => array(
                        'txnid' => $txnid
                    )
                ));
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $data['Cardtracking']=array(
                'cardnumber'=>$cardno,
                'cashierID'=>$cashierid,
                'txnid'=>$txnid,
                'reference_id'=>$reference_id,
                'cashierName'=>$cashiername,
                'customername'=>$name,
                'customerphone'=>$mobile,
                'purpose'=>'withdrawal',
                'oldbalance'=>$oldbal,
                'amount'=>$amount,
                'newbalance'=>$newbal,
                'type'=>2,
                'payment_mode'=>$mode
            );
          
            if($this->Cardtracking->saveAll($data['Cardtracking']))
            {
                $this->Card->query("UPDATE cards SET cardbalance = $newbal,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            
                $response= array('status'=> true,
                    'message'=> "money paid sucessfully",
                    'cardno'=>$cardno,
                    'balance'=>$newbal
                );
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "failed",
                );
            }
        }
        return json_encode($response);
    }
    
    public function carddeactivate()
    {
        $cashierid = $_REQUEST['id'];
        $cardno = $_REQUEST['cardno'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card already Deactivated",
            );
            return json_encode($response);
        }else{
            $this->Card->query("UPDATE cards SET status = 0,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
        
            $response= array('status'=> true,
                'message'=> "Card Deactivated successfully",
            );
        
        }
        return json_encode($response);
    }
    
    public function cardtransfer()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        // $otp = $_REQUEST['otp'];
        $newcardno = $_REQUEST['newcardno'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        // if($otp==''){
        //     $response =array(
        //         'status'=> false,
        //         'message'=> "OTP Missing",
        //     );
        //     return json_encode($response);
        // }
        if($newcardno==''){
            $response =array(
                'status'=> false,
                'message'=> "New Card No Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card Deactivated",
            );
            return json_encode($response);
        }else{
            // $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2,'Card.otp'=>$otp)));
            // if(empty($card))
            // {
            //     $response =array(
            //         'status'=> false,
            //         'message'=> "Wrong OTP",
            //     );
            //     return json_encode($response);
            // }
            $newcard = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$newcardno)));
            if(!empty($newcard))
            {
                $status=$newcard['Card']['status'];
                if($status==1){
                    $response =array(
                        'status'=> false,
                        'message'=> "New Card No Already Exist",
                    );
                    return json_encode($response);
                }else{
                    $response= array('status'=> true,
                        'message'=> "New Card no Already Exist But Card Deactivated"
                    );
                    return json_encode($response);
                }
            }else{
            
                $name=$card['Card']['name'];
                $mobile=$card['Card']['mobile'];
                $oldbal=$card['Card']['cardbalance'];
                
                $data['Card']=array(
                    'cardnumber'=>$newcardno,
                    'cardbalance'=>$oldbal,
                    'name'=>$name,
                    'mobile'=>$mobile,
                    'status'=>2
                );
              
                if($this->Card->saveAll($data['Card']))
                {
                    $this->Card->query("UPDATE cards SET cardbalance = 0,status=0,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
                    
                    do {
                        $txnid = '';
                        for ($i = 0; $i < 10; $i++) {
                            $txnid .= rand(0, 9);
                        }
                        $existingOTP = $this->Cardtracking->find('first', array(
                            'conditions' => array(
                                'txnid' => $txnid
                            )
                        ));
                    } while ($existingOTP); // Continue generating OTP until it doesn't exist
                    
                    $data['Cardtracking']=array(
                        'cardnumber'=>$newcardno,
                        'cashierID'=>$cashierid,
                        'txnid'=>$txnid,
                        'cashierName'=>$cashiername,
                        'customername'=>$name,
                        'customerphone'=>$mobile,
                        'purpose'=>'transferto',
                        'oldbalance'=>0,
                        'amount'=>$oldbal,
                        'newbalance'=>$oldbal,
                        'type'=>1,
                        'payment_mode'=>'transfer'
                    );
                  
                    if($this->Cardtracking->saveAll($data['Cardtracking']))
                    {
                        do {
                            $txnid = '';
                            for ($i = 0; $i < 10; $i++) {
                                $txnid .= rand(0, 9);
                            }
                            $existingOTP = $this->Cardtracking->find('first', array(
                                'conditions' => array(
                                    'txnid' => $txnid
                                )
                            ));
                        } while ($existingOTP); // Continue generating OTP until it doesn't exist
                        
                        $data1['Cardtracking']=array(
                            'cardnumber'=>$cardno,
                            'cashierID'=>$cashierid,
                            'txnid'=>$txnid,
                            'cashierName'=>$cashiername,
                            'customername'=>$name,
                            'customerphone'=>$mobile,
                            'purpose'=>'transferfrom',
                            'oldbalance'=>$oldbal,
                            'amount'=>$oldbal,
                            'newbalance'=>0,
                            'type'=>2,
                            'payment_mode'=>'transfer'
                        );
                        if($this->Cardtracking->saveAll($data1['Cardtracking']))
                        {
                            $response= array('status'=> true,
                                'message'=> "Card Transfer successfully",
                                'cardno'=>$newcardno,
                                'balance'=>$oldbal
                            );
                        }else{
                            $response =array(
                                'status'=> false,
                                'message'=> "failed to save card tracking 101",
                            ); 
                        }
                    }else{
                        $response =array(
                            'status'=> false,
                            'message'=> "failed to save card tracking",
                        );
                    }
                    
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "failed to save card",
                    );
                }
            }
        }
        return json_encode($response);
    }
    
    public function cardcreate()
    {
        $sendmessage= new UtilityController;
        
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $name = $_REQUEST['name'];
        $mobile = $_REQUEST['mobile'];
        $email = $_REQUEST['email'];
        $valid_to = $_REQUEST['validto'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($name==''){
            $response =array(
                'status'=> false,
                'message'=> "Name Missing",
            );
            return json_encode($response);
        }
        if($mobile==''){
            $response =array(
                'status'=> false,
                'message'=> "Mobile no Missing",
            );
            // return json_encode($response);
        }
        
        if($email==''){
            $response =array(
                'status'=> false,
                'message'=> "Email Missing",
            );
            // return json_encode($response);
        }
        if (!preg_match('/^\d{10}$/', $mobile)) {
            $response =array(
                'status'=> false,
                'message'=> "Mobile no is not valid",
            );
            return json_encode($response);
        }
        // print_r();exit;
        if($valid_to==''){
            $response =array(
                'status'=> false,
                'message'=> "Validity Missing",
            );
            //return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(!empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card Already Exist",
            );
            return json_encode($response);
        }else{
            $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>0)));
            if(!empty($card))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Card Already deactivated!! kindly contact to support!!!",
                );
                return json_encode($response);
            }
            $today = date("Y-m-d");
            $currentDate = new DateTime($today);
            $valid_to = $currentDate->modify('+1 day')->format('Y-m-d');

            $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>1)));
            if(!empty($card))
            {
                //$otp = mt_rand(1000, 9999);
                 $otp=1111;
                $cardCharge=0.0;
                $cardCharge=-card_charge;
                $query=$this->Card->query("UPDATE cards SET name = '$name',email = '$email',mobile = '$mobile',valid_to='$valid_to',otp='$otp',cardbalance=$cardCharge,status = '2',sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
                
    //             $message = "Hi $name, please use $otp to login to PhyloPay.";
    //          $sendmessage->message($message,$mobile);
                
                do {
                    $txnid = '';
                    for ($i = 0; $i < 10; $i++) {
                        $txnid .= rand(0, 9);
                    }
                    $existingOTP = $this->Cardtracking->find('first', array(
                        'conditions' => array(
                            'txnid' => $txnid
                        )
                    ));
                } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
                $data1['Cardtracking']=array(
                    'cardnumber'=>$cardno,
                    'cashierID'=>$cashierid,
                    'txnid'=>$txnid,
                    'cashierName'=>$cashiername,
                    'customername'=>$name,
                    'customerphone'=>$mobile,
                    'purpose'=>'create',
                    'oldbalance'=>0,
                    'amount'=>security,
                    'newbalance'=>security,
                    'type'=>3,
                    'payment_mode'=>'security'
                );
            
                if($this->Cardtracking->saveAll($data1['Cardtracking']))
                {
                    do {
                        $txnid = '';
                        for ($i = 0; $i < 10; $i++) {
                            $txnid .= rand(0, 9);
                        }
                        $existingOTP = $this->Cardtracking->find('first', array(
                            'conditions' => array(
                                'txnid' => $txnid
                            )
                        ));
                    } while ($existingOTP); // Continue generating OTP until it doesn't exist
                    
                    $data11['Cardtracking']=array(
                        'cardnumber'=>$cardno,
                        'cashierID'=>$cashierid,
                        'txnid'=>$txnid,
                        'cashierName'=>$cashiername,
                        'customername'=>$name,
                        'customerphone'=>$mobile,
                        'purpose'=>'card_charge',
                        'oldbalance'=>0,
                        'amount'=>-card_charge,
                        'newbalance'=>-card_charge,
                        'type'=>2,
                        'payment_mode'=>'card_charge'
                    );
                    if($this->Cardtracking->saveAll($data11['Cardtracking']))
                    {
                        $response= array('status'=> true,
                            'message'=> "Card Created successfully",
                            'cardno'=>$cardno,
                            'name'=>$name,
                            'email'=>$email,
                            'mobile'=>$mobile,
                            'valid_to'=>$valid_to,
                            'balance'=>-card_charge,
                        );
                    }
                }
            }else{
            
                // $otp = mt_rand(1000, 9999); 
                $otp=1111;
                $data['Card']=array(
                    'cardnumber'=>$cardno,
                    'cardbalance'=>-card_charge,
                    'name'=>$name,
                    'email'=>$email,
                    'mobile'=>$mobile,
                    'valid_to'=>$valid_to,
                    'status'=>2
                );
          
                if($this->Card->saveAll($data['Card']))
                {
        //          $message = "Hi $name, please use $otp to login to PhyloPay.";
        //          $sendmessage->message($message,$mobile);
                    
                    do {
                        $txnid = '';
                        for ($i = 0; $i < 10; $i++) {
                            $txnid .= rand(0, 9);
                        }
                        $existingOTP = $this->Cardtracking->find('first', array(
                            'conditions' => array(
                                'txnid' => $txnid
                            )
                        ));
                    } while ($existingOTP); // Continue generating OTP until it doesn't exist
                
                    $data1['Cardtracking']=array(
                        'cardnumber'=>$cardno,
                        'cashierID'=>$cashierid,
                        'txnid'=>$txnid,
                        'cashierName'=>$cashiername,
                        'customername'=>$name,
                        'customerphone'=>$mobile,
                        'purpose'=>'create',
                        'oldbalance'=>0,
                        'amount'=>security,
                        'newbalance'=>security,
                        'type'=>3,
                        'payment_mode'=>'security'
                    );
                
                    if($this->Cardtracking->saveAll($data1['Cardtracking']))
                    {
                        do {
                            $txnid = '';
                            for ($i = 0; $i < 10; $i++) {
                                $txnid .= rand(0, 9);
                            }
                            $existingOTP = $this->Cardtracking->find('first', array(
                                'conditions' => array(
                                    'txnid' => $txnid
                                )
                            ));
                        } while ($existingOTP); // Continue generating OTP until it doesn't exist
                        
                        $data11['Cardtracking']=array(
                            'cardnumber'=>$cardno,
                            'cashierID'=>$cashierid,
                            'txnid'=>$txnid,
                            'cashierName'=>$cashiername,
                            'customername'=>$name,
                            'customerphone'=>$mobile,
                            'purpose'=>'card_charge',
                            'oldbalance'=>0,
                            'amount'=>-card_charge,
                            'newbalance'=>-card_charge,
                            'type'=>2,
                            'payment_mode'=>'card_charge'
                        );
                        if($this->Cardtracking->saveAll($data11['Cardtracking']))
                        {
                            $response= array('status'=> true,
                                'message'=> "Card Created successfully",
                                'cardno'=>$cardno,
                                'name'=>$name,
                                'email'=>$email,
                                'mobile'=>$mobile,
                                'valid_to'=>$valid_to,
                                'balance'=>-card_charge,
                            );
                        }
                    }
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "failed to save card",
                    ); 
                }
            }
        }
        return json_encode($response);
    }
    
    public function cardcreate_verify()
    {
        $sendlink= new UtilityController;
        
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $otp = $_REQUEST['otp'];
        $pinrequired = $_REQUEST['pinrequired'];
        if(!$pinrequired){
            $pinrequired=0;
        }
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($otp==''){
            $response =array(
                'status'=> false,
                'message'=> "OTP Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.otp'=>$otp)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Wrong OTP",
            );
            return json_encode($response);
        }else{
            $cardid=$card['Card']['id'];
            $name=$card['Card']['name'];
            $mobile=$card['Card']['mobile'];
            
            $this->Card->query("UPDATE cards SET status = '2',pin_required='$pinrequired',sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            
            do {
                $txnid = '';
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existingOTP = $this->Cardtracking->find('first', array(
                    'conditions' => array(
                        'txnid' => $txnid
                    )
                ));
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $data1['Cardtracking']=array(
                'cardnumber'=>$cardno,
                'cashierID'=>$cashierid,
                'txnid'=>$txnid,
                'cashierName'=>$cashiername,
                'customername'=>$name,
                'customerphone'=>$mobile,
                'purpose'=>'create',
                'oldbalance'=>0,
                'amount'=>security,
                'newbalance'=>security,
                'type'=>3,
                'payment_mode'=>'security'
            );
                if($this->Cardtracking->saveAll($data1['Cardtracking']))
                {
                    do {
                        $txnid = '';
                        for ($i = 0; $i < 10; $i++) {
                            $txnid .= rand(0, 9);
                        }
                        $existingOTP = $this->Cardtracking->find('first', array(
                            'conditions' => array(
                                'txnid' => $txnid
                            )
                        ));
                    } while ($existingOTP); // Continue generating OTP until it doesn't exist
                    
                    $data11['Cardtracking']=array(
                        'cardnumber'=>$cardno,
                        'cashierID'=>$cashierid,
                        'txnid'=>$txnid,
                        'cashierName'=>$cashiername,
                        'customername'=>$name,
                        'customerphone'=>$mobile,
                        'purpose'=>'card_charge',
                        'oldbalance'=>0,
                        'amount'=>-card_charge,
                        'newbalance'=>-card_charge,
                        'type'=>2,
                        'payment_mode'=>'card_charge'
                    );
                    if($this->Cardtracking->saveAll($data11['Cardtracking']))
                    {
                        if($pinrequired){
                            $smslink=smslink;
                            $message = "Hi $name, please go to $smslink.$cardid to set your PIN for Gourmet Pay, powered by PhyloPay.";
                            $lin=$sendlink->createpinlinkmsg($message,$mobile);
                        }
                        $response= array('status'=> true,
                            'message'=> "Card Verified successfully",
                            'cardno'=>$cardno,
                            'name'=>$name,
                            'mobile'=>$mobile,
                            'balance'=>-card_charge,
                            'pinrequired'=>$pinrequired
                        );
                    }
                }
        }
        return json_encode($response);
    }
    
    public function dasboarddata()
    {
        $cashierid = $_REQUEST['id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        $card = $this->Cardtracking->query("SELECT SUM(IF(type=1,1,0))+SUM(IF(type=2,1,0)) AS total_txnid, SUM(IF(type=3,1,0)) AS cardissue, SUM(IF(type=1 and purpose='add',amount,0)) AS deposit, SUM(IF(type=2 and purpose='withdrawal',amount,0)) AS deduct FROM cardtracking WHERE cashierID=$cashierid and date(created)='$todayDate'");
        
        if(!empty($card))
        {
            if($card[0][0]['deposit']){
                $deposit=$card[0][0]['deposit'];
            }else{
                $deposit="0";
            }
            if($card[0][0]['deduct']){
                $deduct=$card[0][0]['deduct'];
            }else{
                $deduct="0";
            }
            if($card[0][0]['total_txnid']){
                $total_txnid=$card[0][0]['total_txnid'];
            }else{
                $total_txnid="0";
            }
            if($card[0][0]['cardissue']){
                $cardissue=$card[0][0]['cardissue'];
            }else{
                $cardissue="0";
            }
            
            $response= array('status'=> true,
                'message'=> "success",
                'total_txn' => $total_txnid,
                'card_issued' => $cardissue,   
                'amount_collected' => $deposit,   
                'amount_deducted' => $deduct
            );
        }else{
            $response =array(
                'status'=> false,
                'message'=> "No data found",
            );
        }
        return json_encode($response);
    }
    
    public function card_history()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card Not found ",
            );
            return json_encode($response);
        }else{
            $cardtracks = $this->Cardtracking->find('all', array('conditions'=>array('Cardtracking.cardnumber'=>$cardno),'order' => array('Cardtracking.id' => 'desc')));
            foreach($cardtracks as $cardtrack){
                if($cardtrack['Cardtracking']['type']==1){
                    $type_value='add';
                }elseif($cardtrack['Cardtracking']['type']==2){
                    $type_value='deduct';
                }elseif($cardtrack['Cardtracking']['type']==3){
                    $type_value='security';
                }else{
                    $type_value='refund';
                }
                if($cardtrack['Cardtracking']['cashierName']){
                    $cashierName=$cardtrack['Cardtracking']['cashierName'];
                }else{
                    $cashierName='';
                }
                if($cardtrack['Cardtracking']['customername']){
                    $customername=$cardtrack['Cardtracking']['customername'];
                }else{
                    $customername='';
                }
                if($cardtrack['Cardtracking']['customerphone']){
                    $customerphone=$cardtrack['Cardtracking']['customerphone'];
                }else{
                    $customerphone='';
                }
                if($cardtrack['Cardtracking']['payment_mode']){
                    $payment_mode=$cardtrack['Cardtracking']['payment_mode'];
                }else{
                    $payment_mode='';
                }
                $item[]=array(
                    'id' => $cardtrack['Cardtracking']['id'],
                    'cardnumber' =>  $cardtrack['Cardtracking']['cardnumber'],
                    'cashierID' =>  $cardtrack['Cardtracking']['cashierID'],
                    'txnid' =>  $cardtrack['Cardtracking']['txnid'],
                    'cashierName' =>  $cashierName,
                    'customername' =>  $customername,
                    'customerphone' =>  $customerphone,
                    'purpose' =>  $cardtrack['Cardtracking']['purpose'],
                    'oldbalance' =>  $cardtrack['Cardtracking']['oldbalance'], 
                    'amount' =>  $cardtrack['Cardtracking']['amount'], 
                    'newbalance' =>  $cardtrack['Cardtracking']['newbalance'], 
                    'type' =>  $cardtrack['Cardtracking']['type'], 
                    'type_value' =>  $type_value, 
                    'payment_mode' =>  $payment_mode,  
                    'created' =>  $cardtrack['Cardtracking']['created']
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'users'=>$item
            );
        }
        return json_encode($response);
    }
    
    public function user_modules()
    {
        $id = $_REQUEST['id'];
        
        if(!isset($id)){
            $response['status']= false;
            $response['message']= "user id missing..!";
            return json_encode($response);
        }
        $response = array();
        
        $users = $this->User_module->find('all', array('conditions'=>array('user_id'=>$id,'status'=>1)));
        if(!empty($users))
        {
            $card=false;
            $catalogue=false;
            $reporting=false;
            $ordering=false;
            foreach($users as $user){
                $name=$user['User_module']['name'];
                if($name=='card'){
                    $card=true;
                }
                if($name=='catalogue'){
                    $catalogue=true;
                }
                if($name=='reporting'){
                    $reporting=true;
                }
                if($name=='ordering'){
                    $ordering=true;
                }
            }
            
            $response['status']= true;
            $response['message']= "Success..!";
            $response['id']= $id;
            $response['card']= $card;
            $response['catalogue']= $catalogue;
            $response['reporting']= $reporting;
            $response['ordering']= $ordering;
        }
        else
        {
            $response['status']= false;
            $response['message']= "Failed..!";
        }
        return json_encode($response);
    }
    
    //Ordering API's
    public function category_list()
    {
        $cashierid = $_REQUEST['id'];
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $categoreis = $this->Catalog_category->find('all', array('conditions'=>array('Catalog_category.status'=>1)));
        if(empty($categoreis))
        {
            $response =array(
                'status'=> false,
                'message'=> "Category Not found ",
            );
            return json_encode($response);
        }else{
            foreach($categoreis as $categorei){
                $image='';
                $cat_id=$categorei['Catalog_category']['id'];
                $subitem=[];
                if($categorei['Catalog_category']['is_subcategory']){
                    $subcats = $this->Catalog_subcategory->find('all', array('conditions'=>array('Catalog_subcategory.cat_id'=>$cat_id,'status'=>1)));
                    foreach($subcats as $subcat){
                        $subitem[]=array(
                            'id' => $subcat['Catalog_subcategory']['id'],
                            'name' =>  $subcat['Catalog_subcategory']['name'],
                            'image'=>$image,
                            'created' =>  $subcat['Catalog_subcategory']['created']
                        );
                    }
                }
                $item[]=array(
                    'id' => $categorei['Catalog_category']['id'],
                    'name' =>  $categorei['Catalog_category']['name'],
                    'is_subcategory' =>  $categorei['Catalog_category']['is_subcategory'],
                    'subcategory'=>$subitem,
                    'image'=>$image,
                    'created' =>  $categorei['Catalog_category']['created']
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'category'=>$item
            );
        }
        return json_encode($response);
    }
    
    public function product_list()
    {
        $cashierid = $_REQUEST['id'];
        $catid = $_REQUEST['catid'];
        $subcatid = $_REQUEST['subcatid'];
        if(isset($subcatid)){
            $catid=$subcatid;
        }
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($catid==''){
            $response =array(
                'status'=> false,
                'message'=> "Category Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        if($catid==0){
            $products = $this->Catalog_product->find('all', array('conditions'=>array('Catalog_product.status'=>1)));
        }else{
            $products = $this->Catalog_product->find('all', array(
                'conditions' => array(
                    'Catalog_product.status' => 1,
                    'OR' => array(
                        'Catalog_product.cat_id' => $catid,
                        'Catalog_product.subcat_id' => $catid
                    )
                )
            ));
        }
        
        if(empty($products))
        {
            $response =array(
                'status'=> false,
                'message'=> "Products Not found ",
            );
            return json_encode($response);
        }else{
            foreach($products as $product){
                
                $taxesitems=[];
                $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                foreach($taxess as $tax){
                    $taxesitems[]=array(
                        'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                        'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                        'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                    );
                }
            
            
                $addonitems=[];
                if($product['Catalog_product']['addon']){
                    $addons = $this->Catalog_product_addon->find('all', array('conditions'=>array('Catalog_product_addon.product_id'=>$product['Catalog_product']['id'],'Catalog_product_addon.status'=>1)));
                    foreach($addons as $addon){
                        $addonitems[]=array(
                            'id' => $addon['Catalog_product_addon']['id'],
                            'name' =>  $addon['Catalog_product_addon']['name'],
                            'created' =>  $addon['Catalog_product_addon']['created']
                        );
                    }
                }
                
                if(!$product['Catalog_product']['image']){
                    $product['Catalog_product']['image']='';
                }
                
                if($product['Catalog_product']['image']){
                    $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                }else{
                    $imgpth=''; 
                }        
                $item[]=array(
                    'id' => $product['Catalog_product']['id'],
                    'name' =>  $product['Catalog_product']['name'],
                    'cat_id' =>  $product['Catalog_product']['cat_id'],
                    'cat_name' =>  $product['Catalog_product']['cat_name'],
                    'description' => $product['Catalog_product']['description'],
                    'food_type' =>  $product['Catalog_product']['food_type'],
                    'sort_order' =>  $product['Catalog_product']['sort_order'],
                    'recommended' =>  $product['Catalog_product']['recommended'],
                    'variation' =>  $product['Catalog_product']['variation'],
                    'price' => $product['Catalog_product']['price'],
                    'kds' => $product['Catalog_product']['kds'],
                    'markup_price' =>  $product['Catalog_product']['markup_price'],
                    'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                    'weight' =>  $product['Catalog_product']['weight'],
                    'serves_people' =>  $product['Catalog_product']['serves_people'],
                    'image' => $imgpth,
                    'taxes'=>$taxesitems,
                    'addons'=>$addonitems,
                    'status' =>  $product['Catalog_product']['status'],
                    'created' =>  $product['Catalog_product']['created']
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'products'=>$item
            );
        }
        return json_encode($response);
    }
    
    public function allproduct_list()
    {
        $cashierid = $_REQUEST['id'];
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $categoreis = $this->Catalog_category->find('all', array('conditions'=>array('Catalog_category.status'=>1)));
        if(!empty($categoreis)){
            foreach($categoreis as $categorei){
                $image='';
                $cat_id=$categorei['Catalog_category']['id'];
                
                if($categorei['Catalog_category']['is_subcategory']){
                    $subcats = $this->Catalog_subcategory->find('all', array('conditions'=>array('Catalog_subcategory.cat_id'=>$cat_id,'status'=>1)));
                    foreach($subcats as $subcat){
                        $products = $this->Catalog_product->find('all', array('conditions'=>array('Catalog_product.status'=>1,'Catalog_product.cat_id'=>$subcat['Catalog_subcategory']['id'])));
                        
                        if(!empty($products))
                        {
                            foreach($products as $product){
                                $taxesitems=[];
                                $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                                foreach($taxess as $tax){
                                    $taxesitems[]=array(
                                        'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                        'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                        'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                    );
                                }
                            
                            
                                $addonitems=[];
                                if($product['Catalog_product']['addon']){
                                    $addons = $this->Catalog_product_addon->find('all', array('conditions'=>array('Catalog_product_addon.product_id'=>$product['Catalog_product']['id'],'Catalog_product_addon.status'=>1)));
                                    foreach($addons as $addon){
                                        $addonitems[]=array(
                                            'id' => $addon['Catalog_product_addon']['id'],
                                            'name' =>  $addon['Catalog_product_addon']['name'],
                                            'created' =>  $addon['Catalog_product_addon']['created']
                                        );
                                    }
                                }
                                
                                if($product['Catalog_product']['image']){
                                    $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                                }else{
                                    $imgpth=''; 
                                }        
                                // print_r($imgpth);exit;
                                
                                $item[]=array(
                                    'id' => $product['Catalog_product']['id'],
                                    'name' =>  $product['Catalog_product']['name'],
                                    'cat_id' =>  $product['Catalog_product']['cat_id'],
                                    'cat_name' =>  $product['Catalog_product']['cat_name'],
                                    'description' => $product['Catalog_product']['description'],
                                    'food_type' =>  $product['Catalog_product']['food_type'],
                                    'sort_order' =>  $product['Catalog_product']['sort_order'],
                                    'recommended' =>  $product['Catalog_product']['recommended'],
                                    'variation' =>  $product['Catalog_product']['variation'],
                                    'price' => $product['Catalog_product']['price'],
                                    'kds' => $product['Catalog_product']['kds'],
                                    'markup_price' =>  $product['Catalog_product']['markup_price'],
                                    'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                    'weight' =>  $product['Catalog_product']['weight'],
                                    'serves_people' =>  $product['Catalog_product']['serves_people'],
                                    'image' => $imgpth,
                                    'taxes'=>$taxesitems,
                                    'addons'=>$addonitems,
                                    'status' =>  $product['Catalog_product']['status'],
                                    'created' =>  $product['Catalog_product']['created']
                                );
                            }
                        }
                    }
                }else{
                    $products = $this->Catalog_product->find('all', array('conditions'=>array('Catalog_product.status'=>1,'Catalog_product.cat_id'=>$cat_id)));
                        
                    if(!empty($products))
                    {
                        foreach($products as $product){
                            $taxesitems=[];
                            $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                            foreach($taxess as $tax){
                                $taxesitems[]=array(
                                    'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                    'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                    'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                );
                            }
                        
                        
                            $addonitems=[];
                            if($product['Catalog_product']['addon']){
                                $addons = $this->Catalog_product_addon->find('all', array('conditions'=>array('Catalog_product_addon.product_id'=>$product['Catalog_product']['id'],'Catalog_product_addon.status'=>1)));
                                foreach($addons as $addon){
                                    $addonitems[]=array(
                                        'id' => $addon['Catalog_product_addon']['id'],
                                        'name' =>  $addon['Catalog_product_addon']['name'],
                                        'created' =>  $addon['Catalog_product_addon']['created']
                                    );
                                }
                            }
                            
                            if($product['Catalog_product']['image']){
                                $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                            }else{
                                $imgpth=''; 
                            } 
                            
                            $item[]=array(
                                'id' => $product['Catalog_product']['id'],
                                'name' =>  $product['Catalog_product']['name'],
                                'cat_id' =>  $product['Catalog_product']['cat_id'],
                                'cat_name' =>  $product['Catalog_product']['cat_name'],
                                'description' => $product['Catalog_product']['description'],
                                'food_type' =>  $product['Catalog_product']['food_type'],
                                'sort_order' =>  $product['Catalog_product']['sort_order'],
                                'recommended' =>  $product['Catalog_product']['recommended'],
                                'variation' =>  $product['Catalog_product']['variation'],
                                'price' => $product['Catalog_product']['price'],
                                'kds' => $product['Catalog_product']['kds'],
                                'markup_price' =>  $product['Catalog_product']['markup_price'],
                                'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                'weight' =>  $product['Catalog_product']['weight'],
                                'serves_people' =>  $product['Catalog_product']['serves_people'],
                                'image' => $imgpth,
                                'taxes'=>$taxesitems,
                                'addons'=>$addonitems,
                                'status' =>  $product['Catalog_product']['status'],
                                'created' =>  $product['Catalog_product']['created']
                            );
                        }
                    }
                }
            }
        }
        $response= array('status'=> true,
            'message'=> "success",
            'products'=>$item
        );
        return json_encode($response);
    }

    public function orderhistorysave_table()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }else{
            $location_id = $users['User']['location_id'] ?? '';

            if (isset($_REQUEST['data'])) {
                $data = $_REQUEST['data'];
            } else {
                $response =array(
                    'status'=> false,
                    'message'=> "data not found",
                );
                return json_encode($response);
            }
            
            $datajson=$data;
            $data = json_decode($data, true);
            // print_r($data);exit;
            if(isset($data['table_number'])){
                $tableno=$data['table_number'];
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Table Number missing",
                );
                return json_encode($response);
            }
            
            if(isset($data['tablereference_id'])){
                $tablereference_id=$data['tablereference_id'];
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Table Refrence Id missing",
                );
                return json_encode($response);
            }
            
            $datas['Order_orderhistory_json']=array(
                'reference_id'=>$tablereference_id,
                'table_number'=>$tableno,
                'json'=>$datajson
            );
            
            if($this->Order_orderhistory_json->saveAll($datas['Order_orderhistory_json']))
            {
            }
            

            $device_id=$data['device_id'];
            
            $tables = $this->Order_table->find('first', array(
                'conditions' => array(
                    'Order_table.number' => $tableno,
                    'Order_table.reference_id' => $tablereference_id,
                    'Order_table.status IN' => array(1, 2, 4)
                )
            ));
            if(!empty($tables))
            {
                
                $groupid .= rand(0, 9).$cashierid.time();
                
                $todayDate = date('Y-m-d'); // ensure correct format
                $tdaykot = $this->Order_orderhistory->query("
                    SELECT kot_number 
                    FROM order_orderhistories 
                    WHERE store_id = '$location_id' 
                    ORDER BY id DESC 
                    LIMIT 1
                ");
    
                $kot_no=1;
                if (!empty($tdaykot) && isset($tdaykot[0]['order_orderhistories']['kot_number'])) {
                    $kot_no = $tdaykot[0]['order_orderhistories']['kot_number'] + 1;
                }
                
                $prepTimes = [];
            
                foreach ($data['orderhistory'] as $orderhistory) {
                    $packagechck = $this->Catalog_product->find('first', [
                        'conditions' => [
                            'Catalog_product.id' => $orderhistory['product_id'],
                            'Catalog_product.status' => 1,
                        ],
                        'fields' => ['Catalog_product.id','Catalog_product.preparation_time'],
                        'recursive' => -1
                    ]);
                
                    $prep = !empty($packagechck) ? intval($packagechck['Catalog_product']['preparation_time']) : 0;
                    $prepTimes[] = $prep;
                }
                
                $maxPrep = !empty($prepTimes) ? max($prepTimes) : 0;
                
                foreach($data['orderhistory'] as $orderhistory){
                    $cat_id=$orderhistory['cat_id'];
                    $cat_name=$orderhistory['cat_name'];
                    
                    if(isset($orderhistory['kds'])){
                        $kds=$orderhistory['kds'];
                    }else{
                        $kds=1;
                    }
                    
                    $packagechck = $this->Catalog_product->find('first', [
                        'conditions' => [
                            'Catalog_product.id' => $orderhistory['product_id'],
                            'Catalog_product.status' => 1,
                        ],
                        'fields' => ['Catalog_product.id','Catalog_product.dish_type','Catalog_product.preparation_time'],
                        'recursive' => -1
                    ]);
                    
                    $prep = !empty($packagechck) ? intval($packagechck['Catalog_product']['preparation_time']) : 0;
                    $dish_type=$packagechck['Catalog_product']['dish_type'];
                    
                    if ($maxPrep == 0) {
                        $delaySeconds = 10; // default
                    } elseif ($prep == $maxPrep) {
                        $delaySeconds = 10; // longest prep fires immediately (+ buffer)
                    } else {
                        $diff = max(0, $maxPrep - $prep);
                        $delaySeconds = $diff * 60; // convert minutes → seconds
                    }
                
                    // $fireTime = time() + $delaySeconds;
                    $fireTime = time();
                    $fireTime = date('Y-m-d H:i:s', $fireTime);
                    
                    $datas['Order_orderhistory']=array(
                        'reference_id'=>$tablereference_id,
                        'group_id'=>$groupid,
                        'store_id'=>$orderhistory['store_id'],
                        'cashier_id'=>$cashierid,
                        'category'=>$orderhistory['cat_id'],
                        'category_name'=>$orderhistory['cat_name'],
                        'product_id'=>$orderhistory['product_id'],
                        'product_name'=>$orderhistory['product_name'],
                        'quantity'=>$orderhistory['quantity'],
                        'price'=>$orderhistory['price'],
                        'kds'=>$kds,
                        'dish_type'=>$dish_type,
                        'kot_number'=>$kot_no,
                        'total_tax'=>$orderhistory['total_tax'],
                        'total_tax_percentage'=>$orderhistory['total_tax_percentage'],
                        'total_price'=>$orderhistory['total_price'],
                        'discount'=>$orderhistory['discount'],
                        'table_number'=>$tableno,
                        'remarks'=>$orderhistory['remarks'],
                        'device_id'=>$device_id,
                        'prep_time'=>$prep,
                        'fire_at' => $fireTime,
                        'kds_status' =>3,
                        'is_offer'=>$orderhistory['is_offer'] ?? 0,
                        'offer_id'=>$orderhistory['offer_id'] ?? '',
                        'offer_name'=>$orderhistory['offer_name'] ?? '',
                        'offer_type'=>$orderhistory['offer_type'] ?? ''
                    );
                    if($this->Order_orderhistory->saveAll($datas['Order_orderhistory']))
                    {
                        $lastorder_id = $this->Order_orderhistory->id;
                        
                        foreach($orderhistory['order_tax'] as $tax){
                            $tax_value=round(((($orderhistory['price']*$orderhistory['quantity'])*$tax['tax_percentage'])/100),2);

                            $datas['Order_tax']=array(
                                'orderhistory_id'=>$lastorder_id,
                                'product_id'=>$orderhistory['product_id'],
                                'product_name'=>$orderhistory['product_name'],
                                'store_id'=>$orderhistory['store_id'],
                                'kds'=>$kds,
                                'dish_type'=>$dish_type,
                                'price'=>$orderhistory['price'],
                                'taxable_price'=>round($orderhistory['price']*$orderhistory['quantity'],2),
                                'cat_id'=>$cat_id,
                                'cat_name'=>$cat_name,
                                'quantity'=>$orderhistory['quantity'],
                                'tax_id'=>$tax['id'],
                                'tax_name'=>$tax['tax_name'],
                                'tax_percentage'=>$tax['tax_percentage'],
                                'tax_value'=>$tax_value,
                                'reference_id'=>$tablereference_id
                            );
                            if($this->Order_tax->saveAll($datas['Order_tax']))
                            {
                                // $lastorder_taxid = $this->Order_tax->id;
                            }else{
                                $response['status']= false;
                                $response['message']= "Tax not saved Error:102";
                            }
                        }
                        
                        foreach($orderhistory['selected_modifiers'] as $group_modifier){
                            $modifier_group_id=$group_modifier['modifier_group_id'];
                            $modifier_group_name=$group_modifier['modifier_group_name'];
                            $modifier_group_type=$group_modifier['group_type'];
                            
                            foreach($group_modifier['modifiers'] as $modifier){
                                
                                $modifier_id=$modifier['id'];
                                $modifier_name=$modifier['name'];
                                $modifier_price=$modifier['price'];
                                
                                $datas['Order_modifier']=array(
                                    'orderhistory_id'=>$lastorder_id,
                                    'product_id'=>$orderhistory['product_id'],
                                    'product_name'=>$orderhistory['product_name'],
                                    'modifier_group_id'=>$modifier_group_id,
                                    'modifier_group_name'=>$modifier_group_name,
                                    'modifier_group_type'=>$modifier_group_type,
                                    'modifier_id'=>$modifier_id,
                                    'modifier_name'=>$modifier_name,
                                    'modifier_price'=>$modifier_price,
                                    'quantity'=>$orderhistory['quantity'],
                                    'reference_id'=>$tablereference_id
                                );
                                if($this->Order_modifier->saveAll($datas['Order_modifier']))
                                {
                                    // $lastorder_taxid = $this->Order_tax->id;
                                }else{
                                    $response['status']= false;
                                    $response['message']= "Modifier not saved Error:102";
                                }
                            }
                        }
                        // $this->Order_tax->query("UPDATE order_tax SET orderhistory_id  = '$lastorder_id' WHERE id = '$lastorder_taxid'");
                        
                        $this->Order_table->query("UPDATE order_tables SET status = 2,sync=0,local_sync=0 WHERE number = '$tableno' and status!=4");
            
                        $response['status']= true;
                        $response['message']= "Orderhistory Data Saved Successfully..!";
                        $response['group_id']= $groupid;
                        $response['reference_id']= $tablereference_id;
                    }else{
                        $response['status']= false;
                        $response['message']= "Orderhistory Data not saved Error:101";
                    }
                }
            }else{
                $response['status']= false;
                $response['message']= "Table is not Available";
            }
        }
        return json_encode($response);
    }
    
    public function orderhistorysave_package()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }else{
            $location_id = $users['User']['location_id'] ?? '';
            
            if (isset($_REQUEST['data'])) {
                $data = $_REQUEST['data'];
            } else {
                $response =array(
                    'status'=> false,
                    'message'=> "data not found",
                );
                return json_encode($response);
            }
            
            $data = json_decode($data, true);
            $waiter_id='';
            $waiter_name='';
            $reference_id=$data['reference_id'];
            $device_id=$data['device_id'];
            $name=$data['name'];
            $phone=$data['phone'];
            $address=$data['address'];
            $waiter_id=$data['waiter_id'];
            $waiter_name=$data['waiter_name'];
            
            //txnid check
            $trxchck = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status !='=>0)));
            if(!empty($trxchck))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Reference Id already Exist",
                );
                return json_encode($response);
            }        
            
            if($phone!=''){
                //customer save
                $customerchk = $this->Order_customers->find('first', [
                    'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
                    'fields' => ['Order_customers.id'],
                    'recursive' => -1
                ]);
                
                if (empty($customerchk)) {
                
                // Insert new customer
                    $data = [
                        'Order_customers' => [
                            'phone'   => $phone,
                            'name'    => $name,
                            'address' => $address
                        ]
                    ];
                    
                    $this->Order_table->updateAll(
                        [
                            'Order_table.waiter_id' => "'0'",
                            'Order_table.waiter_name' => "''",
                            'Order_table.customer_name' => "''",
                            'Order_table.customer_phone' => "''",
                            'Order_table.customer_address' => "''",
                            'Order_table.sync' => 0,
                            'Order_table.local_sync' => 0
                        ],
                        ['Order_table.reference_id' => $reference_id]
                    );
                    
                    if (!$this->Order_customers->saveAll($data)) {
                        $response =array(
                            'status'=> false,
                            'message'=> "Customer data not inserted",
                        );
                        return json_encode($response);
                    } 
                } else {
                    $this->Order_customers->id = $customerchk['Order_customers']['id'];
                    $this->Order_customers->save([
                        'name' => $name,
                        'address' => $address
                    ]);
                    $this->Order_table->updateAll(
                        [
                            'Order_table.waiter_id' => "'0'",
                            'Order_table.waiter_name' => "''",
                            'Order_table.customer_name' => "''",
                            'Order_table.customer_phone' => "''",
                            'Order_table.customer_address' => "''",
                            'Order_table.sync' => 0,
                            'Order_table.local_sync' => 0
                        ],
                        ['Order_table.reference_id' => $reference_id]
                    );
                }
            }
            
            //orderhistory save
            $groupid .= rand(0, 9).$cashierid.time();
            
            $todayDate = date('Y-m-d'); // ensure correct format
            $tdaykot = $this->Order_orderhistory->query("
                SELECT kot_number 
                FROM order_orderhistories 
                WHERE store_id = '$location_id' 
                ORDER BY id DESC 
                LIMIT 1
            ");

            $kot_no=1;
            if (!empty($tdaykot) && isset($tdaykot[0]['order_orderhistories']['kot_number'])) {
                $kot_no = $tdaykot[0]['order_orderhistories']['kot_number'] + 1;
            }
            
            $prepTimes = [];
            
            foreach ($data['orderhistory'] as $orderhistory) {
                $prep_timechck = $this->Catalog_product->find('first', [
                    'conditions' => [
                        'Catalog_product.id' => $orderhistory['product_id'],
                        'Catalog_product.status' => 1
                    ],
                    'fields' => ['Catalog_product.id','Catalog_product.preparation_time'],
                    'recursive' => -1
                ]);
            
                $prep = !empty($prep_timechck) ? intval($prep_timechck['Catalog_product']['preparation_time']) : 0;
                $prepTimes[] = $prep;
            }
            
            $maxPrep = !empty($prepTimes) ? max($prepTimes) : 0;

            foreach($data['orderhistory'] as $orderhistory){
                $order=false;
                $cat_id=$orderhistory['cat_id'];
                $cat_name=$orderhistory['cat_name'];
                $store_id = $orderhistory['store_id'];
                
                if(isset($orderhistory['kds'])){
                    $kds=$orderhistory['kds'];
                }else{
                    $kds=1;
                }
                
                $package = 0;
                
                $packagechck = $this->Catalog_product->find('first', [
                    'conditions' => [
                        'Catalog_product.id' => $orderhistory['product_id'],
                        'Catalog_product.status' => 1,
                        'Catalog_product.package' => 1
                    ],
                    'fields' => ['Catalog_product.id','Catalog_product.preparation_time'], // only fetch needed field
                    'recursive' => -1
                ]);
                
                if (!empty($packagechck)) {
                    $package = 1;
                }
                
                $prep_timechck = $this->Catalog_product->find('first', [
                    'conditions' => [
                        'Catalog_product.id' => $orderhistory['product_id'],
                        'Catalog_product.status' => 1
                    ],
                    'fields' => ['Catalog_product.id','Catalog_product.dish_type','Catalog_product.preparation_time'], // only fetch needed field
                    'recursive' => -1
                ]);
                $prep = !empty($prep_timechck) ? intval($prep_timechck['Catalog_product']['preparation_time']) : 0;
                $dish_type = $prep_timechck['Catalog_product']['dish_type'];
                
                if ($maxPrep == 0) {
                    $delaySeconds = 10; // default
                } elseif ($prep == $maxPrep) {
                    $delaySeconds = 10; // longest prep fires immediately (+ buffer)
                } else {
                    $diff = max(0, $maxPrep - $prep);
                    $delaySeconds = $diff * 60; // convert minutes → seconds
                }
                
                // $fireTime = time() + $delaySeconds;
                
                $fireTime = time();
                $fireTime=date('Y-m-d H:i:s', $fireTime);
                
                $datas['Order_orderhistory']=array(
                    'reference_id'=>$reference_id,
                    'group_id'=>$groupid,
                    'cashier_id'=>$cashierid,
                    'category'=>$orderhistory['cat_id'],
                    'category_name'=>$orderhistory['cat_name'],
                    'product_id'=>$orderhistory['product_id'],
                    'product_name'=>$orderhistory['product_name'],
                    'quantity'=>$orderhistory['quantity'],
                    'price'=>$orderhistory['price'],
                    'package'=>$package,
                    'dish_type'=>$dish_type,
                    'kds'=>$kds,
                    'kot_number'=>$kot_no,
                    'total_tax'=>$orderhistory['total_tax'],
                    'total_tax_percentage'=>$orderhistory['total_tax_percentage'],
                    'total_price'=>$orderhistory['total_price'],
                    'discount'=>$orderhistory['discount'],
                    'remarks'=>$orderhistory['remarks'],
                    'device_id'=>$device_id,
                    'prep_time'=>$prep,
                    'fire_at' =>  $fireTime,
                    'store_id'=>$store_id,
                    'kds_status'=> 3,
                    'is_offer'=>$orderhistory['is_offer'] ?? 0,
                    'offer_id'=>$orderhistory['offer_id'] ?? '',
                    'offer_name'=>$orderhistory['offer_name'] ?? '',
                    'offer_type'=>$orderhistory['offer_type'] ?? ''
                );
                if($this->Order_orderhistory->saveAll($datas['Order_orderhistory']))
                {
                    $order=true;
                    $lastorder_id = $this->Order_orderhistory->id;
                    
                    foreach($orderhistory['order_tax'] as $tax){
                        $datas['Order_tax']=array(
                            'orderhistory_id'=>$lastorder_id,
                            'store_id'=>$orderhistory['store_id'],
                            'product_id'=>$orderhistory['product_id'],
                            'product_name'=>$orderhistory['product_name'],
                            'kds'=>$kds,
                            'dish_type'=>$dish_type,
                            'price'=>$orderhistory['price'],
                            'taxable_price'=>round($orderhistory['price']*$orderhistory['quantity'],2),
                            'cat_id'=>$cat_id,
                            'cat_name'=>$cat_name,
                            'quantity'=>$orderhistory['quantity'],
                            'tax_id'=>$tax['id'],
                            'tax_name'=>$tax['tax_name'],
                            'tax_percentage'=>$tax['tax_percentage'],
                            'tax_value'=>$tax['tax_value'],
                            'reference_id'=>$reference_id,
                            'store_id'=>$store_id
                        );
                        if($this->Order_tax->saveAll($datas['Order_tax']))
                        {
                            // $lastorder_taxid = $this->Order_tax->id;
                        }else{
                            $response['status']= false;
                            $response['message']= "Tax not saved Error:102";
                        }
                    }
                    
                    
                    foreach($orderhistory['selected_modifiers'] as $group_modifier){
                            $modifier_group_id=$group_modifier['modifier_group_id'];
                            $modifier_group_name=$group_modifier['modifier_group_name'];
                            $modifier_group_type=$group_modifier['group_type'];
                            
                            foreach($group_modifier['modifiers'] as $modifier){
                                
                                $modifier_id=$modifier['id'];
                                $modifier_name=$modifier['name'];
                                $modifier_price=$modifier['price'];
                                
                                $datas['Order_modifier']=array(
                                    'orderhistory_id'=>$lastorder_id,
                                    'product_id'=>$orderhistory['product_id'],
                                    'product_name'=>$orderhistory['product_name'],
                                    'modifier_group_id'=>$modifier_group_id,
                                    'modifier_group_name'=>$modifier_group_name,
                                    'modifier_group_type'=>$modifier_group_type,
                                    'modifier_id'=>$modifier_id,
                                    'modifier_name'=>$modifier_name,
                                    'modifier_price'=>$modifier_price,
                                    'quantity'=>$orderhistory['quantity'],
                                    'reference_id'=>$reference_id,
                                    'store_id'=>$store_id
                                );
                                if($this->Order_modifier->saveAll($datas['Order_modifier']))
                                {
                                    // $lastorder_taxid = $this->Order_tax->id;
                                }else{
                                    $response['status']= false;
                                    $response['message']= "Modifier not saved Error:102";
                                }
                            }
                        }
                    // $this->Order_tax->query("UPDATE order_tax SET orderhistory_id  = '$lastorder_id' WHERE id = '$lastorder_taxid'");
                }else{
                    $response['status']= false;
                    $response['message']= "Orderhistory Data not saved Error:101";
                }
            }
            // 1. Set package=1 for packaged items using JOIN (efficient)
            $this->Order_orderhistory->query("
                UPDATE order_orderhistories o
                JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
                SET o.package = 1,o.sync=0,o.local_sync=0
                WHERE o.reference_id = '$reference_id' AND o.status != 0
            ");
            
            $this->Order_tax->query("
                UPDATE order_tax t
                JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
                SET t.package = 1,t.sync=0,t.local_sync=0
                WHERE t.reference_id = '$reference_id' AND t.status = 1
            ");            
                        
            // 2. Get total packaged quantity
            $total_package = 0;
            $totalpackagechkorder = $this->Order_orderhistory->query("
                SELECT SUM(package) AS total_package
                FROM order_orderhistories 
                WHERE reference_id = '$reference_id' AND status != 0 AND package = 1
            ");
            $packagechngchk=false;
            if (!empty($totalpackagechkorder[0][0]['total_package'])) {
                
                $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                    ? $totalpackagechkorder[0][0]['total_package'] 
                    : 0;
                      
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$reference_id' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$reference_id' AND package = 1 AND status = 1
                        )
                    ");
                
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
            
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    
                    $orderdata = $this->ordercomputewithpackagediscount($reference_id, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }
    
            if($order){
                $todayDate = date("Y-m-d");
                $currenttime=date("H:i:s");
                
                $locations = $this->Order_orderhistory->query("SELECT store_id FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0 group BY store_id");
                
                foreach($locations as $location){
                    $location_id = $location['order_orderhistories']['store_id'];
                    
                    $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                    $token=$tdaytrx['0']['0']['tkn']+1;
                    
                    $orderdata=$this->Order_orderhistory->query("SELECT SUM(price) as price,sum(discount) as discount,sum(total_tax) as total_tax,SUM(total_price) as total_price FROM `order_orderhistories` WHERE reference_id='$reference_id' and store_id='$location_id' and status!=0");
                    $updated_discount=0;
                    $updated_tax=0;
                    $updated_final_amount=0;
                    
                    if($packagechngchk){
                        $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$reference_id' AND status = 1 and store_id='$location_id' GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$reference_id' AND ot.package = 0  and ot.store_id='$location_id' AND ot.status = 1");
                        if(!empty($orderstaxdatas))
                        {
                            $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                            $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                            $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                        }
                    }
                    // $finalamount = round(($orderdata[0][0]['total_price']+$orderdata[0][0]['total_tax'])-$orderdata[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                    // $roundfinalamount = round(($orderdata[0][0]['total_price']+$orderdata[0][0]['total_tax'])-$orderdata[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                    $rawAmount = ($orderdata[0][0]['total_price']+$orderdata[0][0]['total_tax'])-$orderdata[0][0]['discount']-$updated_final_amount;
                    $finalamount = round($rawAmount);
                    $roundfinalamount = round($rawAmount, 2);

                    $round_amount = $finalamount - $roundfinalamount;
                    
                    $datas['Order_transaction']=array(
                        'reference_id'=>$reference_id,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'price'=>$orderdata[0][0]['total_price']-$updated_discount,
                        'total_tax'=>round($orderdata[0][0]['total_tax']-$updated_tax,3),
                        'discount'=>$orderdata[0][0]['discount'] ?? 0,
                        'amount'=>$finalamount,
                        'round'=>round($round_amount,2),
                        'name'=>$name,
                        'phone'=>$phone,
                        'address'=>$address,
                        'waiter_id'=>$waiter_id,
                        'waiter_name'=>$waiter_name,
                        'tokenno'=>$token,
                        'createtime'=>$currenttime,
                        'store_id'=>$location_id,
                        'group_id'=>$groupid
                    );
                    
                    if($this->Order_transaction->saveAll($datas['Order_transaction']))
                    {
                        $dbsave=true;
                        $error = '';
                    }else{
                        $dbsave=false;
                        $error = $store_id;
                    }
                }    
                
                
                if($dbsave)
                {
                    $response['status']= true;
                    $response['message']= "Transaction Data Saved Successfully..!";
                }else{
                    $response['status']= false;
                    $response['message']= "Transaction Data not saved Error for store - ".$error;
                }
                
            }
        }
        
        return json_encode($response);
    }
        
    public function orderpaymentsave()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }else{
            if (isset($_REQUEST['data'])) {
                $data = $_REQUEST['data'];
            } else {
                $response =array(
                    'status'=> false,
                    'message'=> "data not found",
                );
                return json_encode($response);
            }
            
            $data = json_decode($data, true);
            
            $reference_id=$data['reference_id'];
            $device_id=$data['device_id'];
            
            //txn_amount_total sum of payment
            $transactions = $this->Order_transaction->find('first', array(
                'fields' => array('SUM(Order_transaction.amount) AS total_amount'),
                'conditions' => array(
                    'Order_transaction.reference_id' => $reference_id,
                    'Order_transaction.status' => 1
                )
            ));
            
            $total_txn_Amount = !empty($transactions[0]['total_amount']) ? $transactions[0]['total_amount'] : 0;
            
            if (empty($transactions[0]['total_amount'])) {
                $response = array(
                    'status' => false,
                    'message' => "Transaction not found",
                );
                return json_encode($response);
            } else{
                //checkloop  $reference_id from transaction 
                $check_refernce_with_store = $this->Order_transaction->find('all', array(
                    'fields' => array('store_id','id','amount'),
                    'conditions' => array(
                        'Order_transaction.reference_id' => $reference_id,
                        'Order_transaction.status' => 1
                    )
                ));
                
                foreach($check_refernce_with_store as $ref_store){
                
                    $store_id=$ref_store['Order_transaction']['store_id'];
                    $txn_table_id=$ref_store['Order_transaction']['id'];
                    $txn_amount=$ref_store['Order_transaction']['amount'];
                
                    foreach($data['payment'] as $payment){
                        
                        //save store id,txn table id ,round  - 50
                        //calulated amount percent = $payment['amount']/ txn_amount_total
                        // 50/100 =0.333
                        // final_payment= txn_amount * calulated amount percent
                        //round 
                        
                        $amount_percent = $payment['amount'] / $total_txn_Amount;
                        $final_payment = round($txn_amount * $amount_percent);
                        $actual_payment = round($txn_amount * $amount_percent,2);
                        
                        $round = $final_payment - $actual_payment;
                    
                        //round value need to check
                        $datas['Order_payment']=array(
                            'reference_id'=>$reference_id,
                            'device_id'=>$device_id,
                            'cashier_id'=>$cashierid,
                            'type'=>$payment['type'],
                            'type_value'=>$payment['type_value'],
                            'amount'=>$final_payment,
                            'remarks'=>$payment['remarks'],
                            'store_id'=>$store_id,
                            'txn_table_id'=>$txn_table_id,
                            'round'=>round($round,2)
                        );
                        
                        if($this->Order_payment->saveAll($datas['Order_payment']))
                        {
                            $finalpayment=0;
                            $finalamount=0;
                            $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
                            if($allpayments){
                                $finalpayment=$allpayments[0][0]['pay_amount']; //150
                            }
                            
                            $finalamount=$total_txn_Amount ?? 0; //txn_amount_total
                        
                            $amount_diff=$finalamount-$finalpayment;
                            if($amount_diff<1){
                                   
                                $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                                $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='$type_value',sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                                $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                                $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                                
                                
                                //stock update
                                $stockupdate=$this->stock_update($reference_id);
                                if($stockupdate){
                                    $response['status']= true;
                                    $response['message']= "Payment Data Saved Successfully..!";
                                    $response['full_payment']= true;
                                }else{
                                    $response['status']= true;
                                    $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                                    $response['full_payment']= true;
                                }
                            }else{
                                $response['status']= true;
                                $response['message']= "Payment Data Saved Successfully..!";
                                $response['full_payment']= false;
                            }            
                        }else{
                            $response['status']= false;
                            $response['message']= "Payment Data not saved Error:102";
                            $response['full_payment']= false;
                        }
                    }
                    //loop end txn
                }
            }
        }
        return json_encode($response);
    }
    
    public function reprint_kot()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        $group_id = $_REQUEST['group_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        if($group_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Group Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $orderitems=[];
        
        $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and group_id='$group_id' and status!=0 ");
        // print_r("SELECT id,reference_id,group_id,cashier_id,category,category_name,product_id,product_name,SUM(quantity) as quantity,sum(price) as price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0 group BY product_id");exit;
        if(!empty($orderss))
        {
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                
                // $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=$discper[0]['order_tax']['discount_percentage'];
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'pax' =>  $orders['Order_transaction']['pax'],
                    'created' =>  $orders['Order_transaction']['created']
                );
            }
        }
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $waiter_check = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$reference_id)));
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'waiter_name'=>$waiter_check['Order_table']['waiter_name'] ?? 'NA',
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function bill_table()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['customer_pax'];
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];
        
        
        //txnid check status
        $trxchck = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$table_referenceid,'Order_transaction.status !='=>0)));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        //chk package value in table - item in ordergistory link quanti*package
        //discount update in ordertax
        $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
        if(!empty($orderss))
        {
            if($orderss[0][0]['total_price']<1){
                $response =array(
                    'status'=> false,
                    'message'=> "There is no item to bill. Please Check..!",
                );
                return json_encode($response);
            }
            
            $todayDate = date("Y-m-d");
            $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
            $token=$tdaytrx['0']['0']['tkn']+1;
            $currenttime=date("H:i:s");
            
            $datas['Order_transaction']=array(
                'reference_id'=>$table_referenceid,
                'device_id'=>$device_id,
                'cashier_id'=>$cashierid,
                'price'=>round($orderss[0][0]['total_price'],2),
                'total_tax'=>round($orderss[0][0]['total_tax'],2),
                'discount'=>round($orderss[0][0]['discount'],2),
                'amount'=>round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']),
                'round'=>round(round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount'])-($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount'],2),
                'name'=>$name,
                'phone'=>$phone,
                'address'=>$address,
                'tokenno'=>$token,
                'table_number'=>$table_number,
                'pax'=>$pax,
                'waiter_id'=>$waiter_id,
                'waiter_name'=>$waiter_name,
                'is_takeaway' => $is_takeaway,
                'createtime'=>$currenttime
            );
            if($this->Order_transaction->saveAll($datas['Order_transaction']))
            {
                $this->Order_table->query("UPDATE order_tables SET status = 3,sync=0,local_sync=0 WHERE reference_id = '$table_referenceid'");
        
                $response['status']= true;
                $response['message']= "Bill Generated Successfully..!";
            }else{
                $response['status']= false;
                $response['message']= "Transaction Data not saved Error:103";
            }
        }
        
        return json_encode($response);
    }
    
    public function ordercomputewithpackagediscount($txnid=null,$user_id=null,$product_id=0,$discount=0)
    {
        $response['status']=false;
        $totalservicechg=0;
        $totalprice=0;
        $totaltax1=0;
        $totaltax2=0;
        $totaldiscount=0;
        $sc=0;
        $is_sc=0;
        if($is_sc==1){
            $sc=servicecharge;
        }
        $discq="(((Order_orderhistory.total_price)-(Order_orderhistory.discount))*$discount/100)";
        $priceq="((Order_orderhistory.total_price)-(Order_orderhistory.discount))";
        
        $this->Order_orderhistory->virtualFields = array('tdisc'=>"SUM($discq)",'tservicechg'=>"SUM(($priceq-$discq)*($sc/100))",'tprice'=>"SUM($priceq)",'total_tax'=>"SUM(($priceq+(($priceq-$discq)*($sc/100))-$discq)*((Order_orderhistory.total_tax_percentage)/100))");  
        $orderhistories=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.reference_id'=>$txnid,'Order_orderhistory.product_id'=>$product_id,'Order_orderhistory.status !=' =>0),'fields'=>array('product_id','tdisc','Order_orderhistory.reference_id','tprice','total_tax','tservicechg')));
        if(!empty($orderhistories['Order_orderhistory']['reference_id'])){
            $response['status']=true;
            $totalservicechg=round($orderhistories['Order_orderhistory']['tservicechg'],2);
            $totalprice=round($orderhistories['Order_orderhistory']['tprice'],2);
            $totaltax=round($orderhistories['Order_orderhistory']['total_tax'],2);
            $totaldiscount=round($orderhistories['Order_orderhistory']['tdisc'],2);
            
            //tax update
            $discq="(((Order_orderhistory.price)-(Order_orderhistory.discount))*$discount/100)";
            $priceq="((Order_orderhistory.price)-(Order_orderhistory.discount))";
            
            $taxes=[];
            
            $this->Order_orderhistory->virtualFields = array('tamount'=>"($priceq+(($priceq-$discq)*($sc/100))-$discq)");  
            $neworderhistories=$this->Order_orderhistory->find('all',array('conditions'=>array('Order_orderhistory.reference_id'=>$txnid,'Order_orderhistory.product_id'=>$product_id,'Order_orderhistory.cashier_id'=>$user_id,'Order_orderhistory.status !=' =>0),'fields'=>array('Order_orderhistory.reference_id','tamount','product_id','price','id')));
            foreach($neworderhistories as $data){
                $orderhistoryid=$data['Order_orderhistory']['id'];
                $reference_id=$data['Order_orderhistory']['reference_id'];
                $product_id=$data['Order_orderhistory']['product_id'];
                $tamount=$data['Order_orderhistory']['tamount'];
                $price=$data['Order_orderhistory']['price'];
                
                $taxitem=$this->Order_tax->find('all',array('conditions'=>array('Order_tax.reference_id'=>$txnid,'Order_tax.product_id'=>$product_id,'Order_tax.status !='=>0,'Order_tax.orderhistory_id'=>$orderhistoryid)));
                foreach($taxitem as $item){
                    $id=$item['Order_tax']['id'];
                    $tax_id=$item['Order_tax']['tax_id'];
                    $tax_percentage=$item['Order_tax']['tax_percentage'];
                    $quantity=$item['Order_tax']['quantity'];
                    $taxamount=round($tamount*$quantity,2);
                    $taxvalue=round((($tamount*$quantity*$tax_percentage)/100),2);
                    
                    $db = $this->Order_tax->getDataSource();
                    
                    try {
                        $this->Order_tax->updateAll(
                            [
                                'Order_tax.taxable_price'       => $taxamount,
                                'Order_tax.tax_value'           => $taxvalue,
                                'Order_tax.discount_percentage' => $discount,
                                'Order_tax.sync'                => 0,
                                'Order_tax.local_sync'          => 0
                            ],
                            [
                                'Order_tax.id' => $id
                            ]
                        );
                    
                        if ($db->lastError()) {
                            $this->trackUser($txnid,$users, 'ordercomputewithpackagediscount (silent)', [
                                'ref_id'    => $txnid,
                                'taxamount' => $taxamount,
                                'taxvalue'  => $taxvalue,
                                'discount'  => $discount,
                                'id'        => $id,
                                'db_error'  => $db->lastError()
                            ]);
                        }
                    } catch (Exception $e) {
                        $this->trackUser($txnid,$users, 'ordercomputewithpackagediscount (exception)', [
                            'ref_id'    => $txnid,
                            'taxamount' => $taxamount,
                            'taxvalue'  => $taxvalue,
                            'discount'  => $discount,
                            'id'        => $id,
                            'error'     => $e->getMessage()
                        ]);
                    }


                    // $this->Order_tax->query("UPDATE order_tax SET taxable_price = '$taxamount',tax_value='$taxvalue',discount_percentage='$discount',sync=0,local_sync=0 WHERE id = '$id'");
                }
            }
            
            $response['totalservicechg']=$totalservicechg;
            $response['totalprice']=$totalprice;
            $response['totaltax']=$totaltax;
            $response['totaldiscount']=$totaldiscount;
        }
        // print_r($response);exit;
        return $response;
    }
    
    
    public function orderpaymentsave_table()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }else{
            if (isset($_REQUEST['data'])) {
                $data = $_REQUEST['data'];
            } else {
                $response =array(
                    'status'=> false,
                    'message'=> "data not found",
                );
                return json_encode($response);
            }
            
            $data = json_decode($data, true);
            
            $reference_id=$data['reference_id'];
            $device_id=$data['device_id'];
            
            //payment save
            
            $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status'=>1)));
            if(empty($transactions))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Transaction not found",
                );
                return json_encode($response);
            }else{
                $store_id=$transactions['Order_transaction']['store_id'];
                
                foreach($data['payment'] as $payment){
            
                    $datas['Order_payment']=array(
                        'reference_id'=>$reference_id,
                        'store_id'=>$store_id,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'type'=>$payment['type'],
                        'type_value'=>$payment['type_value'],
                        'amount'=>$payment['amount'],
                        'remarks'=>$payment['remarks']
                    );
                    if($this->Order_payment->saveAll($datas['Order_payment']))
                    {
                        $finalpayment=0;
                        $finalamount=0;
                        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
                        if($allpayments){
                            $finalpayment=$allpayments[0][0]['pay_amount'];
                        }
                        if($transactions){
                            $finalamount=$transactions['Order_transaction']['amount'];
                        }
                        $amount_diff=$finalamount-$finalpayment;
                        if($amount_diff<1){
                            
                            $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                            $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='$type_value',sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                            $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                            $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                            
                            do {
                                $pin = 'TX' . $cashierid . date('Y') . uniqid();
                                // $pin = uniqid();
                            } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
                            
                            $tablestatus = $this->Order_table->find('first', array('conditions'=>array('reference_id'=>$reference_id,'is_takeaway'=>1)));
                            if(!empty($tablestatus))
                            {   
                                $this->Order_table->query("UPDATE order_tables SET status=0,sync=0,local_sync=0  WHERE reference_id = '$reference_id'");
                            }else{
                                $this->Order_table->query("UPDATE order_tables SET customer_name='',customer_phone='',customer_address='',customer_pax=1,status = 1,reference_id='$pin',is_alert=0,sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                            }

                            $stockupdate=$this->stock_update($reference_id);
                            if(!$stockupdate){
                                $response['status']= true;
                                $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                                $response['full_payment']= true; 
                            }
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..!";
                            $response['full_payment']= true;
                        }else{
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..!";
                            $response['full_payment']= false;
                        }
                    }else{
                        $response['status']= false;
                        $response['message']= "Payment Data not saved Error:102";
                        $response['full_payment']= false;
                    }
                }
            }
        }
        return json_encode($response);
    }
    
    public function swap_table()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $from_table = $_REQUEST['from_reference_id'];
        if($from_table==''){
            $response =array(
                'status'=> false,
                'message'=> "From Reference id is Missing",
            );
            return json_encode($response);
        }
        
        $to_table = $_REQUEST['to_reference_id'];
        if($to_table==''){
            $response =array(
                'status'=> false,
                'message'=> "To Reference id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $chktransaction=$this->Order_table->find('first',array('conditions'=>array('Order_table.status'=>2,'Order_table.reference_id'=>$from_table)));
        //print_r($chktransaction);exit;
        
        if(empty($chktransaction)){
            $response['message']= "Option not available for source table!";
            return json_encode($response);
        }
        $from_table_no=$chktransaction['Order_table']['number'];
        
        $chktable=$this->Order_table->find('first',array('conditions'=>array('Order_table.status'=>1,'Order_table.reference_id'=>$to_table)));
        if(empty($chktable)){
            $response['message']= "Option not available for Destination table!";
            return json_encode($response);
        }
        $to_table_no=$chktable['Order_table']['number'];
        
        do {
            // $pin = uniqid();
            $pin = 'TX' . $cashierid . date('Y') . uniqid();
        } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
        $this->Order_table->query("UPDATE order_tables SET status = 1,reference_id='$pin',sync=0,local_sync=0 WHERE reference_id = '$from_table'");
        
        $this->Order_table->query("UPDATE order_tables SET status = 2,reference_id='$from_table',sync=0,local_sync=0 WHERE reference_id = '$to_table'");
        
        // Update table_number in order history and transactions to reflect the new physical table
        $this->Order_orderhistory->query("UPDATE order_orderhistories SET table_number='$to_table_no', sync=0, local_sync=0 WHERE reference_id='$from_table' AND status!=0");
        $this->Order_transaction->query("UPDATE order_transactions SET table_number='$to_table_no', sync=0, local_sync=0 WHERE reference_id='$from_table' AND status!=0");
         
        // Update KDS tracks for the moved table
        $this->Kds_track->query("UPDATE kds_tracks SET table_no='$to_table_no', sync=0, local_sync=0 WHERE order_reference_id='$from_table' AND status!=0");

        $response['status']= true;
        $response['message']= "Swap Successfully..!";

        return json_encode($response);
    }
    
    public function remove_item()
    {
        // $response['status']= false;
        // $response['message']= "fail";
        $response['status']= false;
        $response['message']= "fail";
        
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $order_id = $_REQUEST['order_id'];
        if($order_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Order id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $chktransaction=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.status'=>1,'Order_orderhistory.id'=>$order_id)));
        
        if(empty($chktransaction)){
            $response['message']= "Order Item not found";
            return json_encode($response);
        }
        $reference_id=$chktransaction['Order_orderhistory']['reference_id'];
        $product_id=$chktransaction['Order_orderhistory']['product_id'];
        $quantity=$chktransaction['Order_orderhistory']['quantity'];
    
        // $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 0 WHERE id = '$order_id'");
        // $this->Order_tax->query("UPDATE order_tax SET status = 0 WHERE reference_id = '$reference_id' AND orderhistory_id = '$order_id'");
        
        // Soft delete order history
        $this->Order_orderhistory->updateAll(
            ['Order_orderhistory.status' => 0,],
            ['Order_orderhistory.id' => $order_id]
        );
        $this->Order_orderhistory->updateAll(
            array(
                'Order_orderhistory.sync' => 0,
                'Order_orderhistory.local_sync' => 0
            ),
            array(
                'Order_orderhistory.id' => $order_id   // or reference_id condition
            )
        );
        
        // Soft delete related taxes
        $this->Order_tax->updateAll(
            ['status' => 0],
            ['orderhistory_id' => $order_id]
        );
        $this->Order_tax->updateAll(
            array(
                'Order_tax.sync' => 0,
                'Order_tax.local_sync' => 0
            ),
            array(
                'Order_tax.orderhistory_id' => $order_id   // or reference_id condition
            )
        );

        $this->Order_modifier->updateAll(
            ['Order_modifier.status' => 0],
            ['Order_modifier.orderhistory_id' => $order_id]
        );
        $this->Order_modifier->updateAll(
            array(
                'Order_modifier.sync' => 0,
                'Order_modifier.local_sync' => 0
            ),
            array(
                'Order_modifier.orderhistory_id' => $order_id   // or reference_id condition
            )
        );
        
        $response['status']= true;
        $response['message']= "Item Removed Successfully..!";

        return json_encode($response);
    }
    
    public function quantity_increase()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $order_id = $_REQUEST['order_id'];
        if($order_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Order id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $orderss = $this->Order_orderhistory->find('first', array('conditions'=>array('id'=>$order_id,'status !='=>0)));
        if(!empty($orderss))
        {
            $newquantity=$orderss['Order_orderhistory']['quantity']+1;
            $price_value=$newquantity*$orderss['Order_orderhistory']['price'];
            $total_tax_percentage=$orderss['Order_orderhistory']['total_tax_percentage'];
            $total_tax=round(((($price_value-$orderss['Order_orderhistory']['discount'])*$total_tax_percentage)/100),2);
            
            $total_price=round($price_value,2);
            
            $this->Order_orderhistory->query("UPDATE order_orderhistories SET quantity=$newquantity,total_price=$total_price,total_tax=$total_tax,sync=0,local_sync=0 WHERE id = '$order_id'");
            $this->Order_modifier->query("UPDATE order_modifier SET quantity=$newquantity,sync=0,local_sync=0 WHERE orderhistory_id = '$order_id'");
            
            $reference_id=$orderss['Order_orderhistory']['reference_id'];
            $product_id=$orderss['Order_orderhistory']['product_id'];
            $tamount=$total_price;
            $price=$orderss['Order_orderhistory']['price'];
            $taxitem=$this->Order_tax->find('all',array('conditions'=>array('Order_tax.orderhistory_id'=>$order_id,'Order_tax.reference_id'=>$reference_id,'Order_tax.product_id'=>$product_id,'Order_tax.status !='=>0)));
            foreach($taxitem as $item){
                $id=$item['Order_tax']['id'];
                $tax_percentage=$item['Order_tax']['tax_percentage'];
                $quantity=$item['Order_tax']['quantity']+1;
                $taxamount=round($price*$quantity,2);
                $taxvalue=round((($price*$quantity*$tax_percentage)/100),2);
                
                $this->Order_tax->query("UPDATE order_tax SET quantity=$quantity,taxable_price = '$taxamount',tax_value='$taxvalue',sync=0,local_sync=0 WHERE id = '$id'");
            }
            
            
            $response['status']= true;
            $response['message']= "Quantity Increased Successfully..!";

        
        }else{
            $response['status']= false;
            $response['message']= "Order item not found..!";

        }
        
        
        return json_encode($response);
    }
    
    public function quantity_decrease()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $order_id = $_REQUEST['order_id'];
        if($order_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Order id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $orderss = $this->Order_orderhistory->find('first', array('conditions'=>array('id'=>$order_id,'quantity >'=>1,'status !='=>0)));
        if(!empty($orderss))
        {
            $newquantity=$orderss['Order_orderhistory']['quantity']-1;
            $price_value=$newquantity*$orderss['Order_orderhistory']['price'];
            $total_tax_percentage=$orderss['Order_orderhistory']['total_tax_percentage'];
            $total_tax=round(((($price_value-$orderss['Order_orderhistory']['discount'])*$total_tax_percentage)/100),2);
            
            $total_price=round($price_value,2);
            
            $this->Order_orderhistory->query("UPDATE order_orderhistories SET quantity=$newquantity,total_price=$total_price,total_tax=$total_tax,sync=0,local_sync=0 WHERE id = '$order_id'");
            $this->Order_modifier->query("UPDATE order_modifier SET quantity=$newquantity,sync=0,local_sync=0 WHERE orderhistory_id = '$order_id'");
            
            $reference_id=$orderss['Order_orderhistory']['reference_id'];
            $product_id=$orderss['Order_orderhistory']['product_id'];
            $tamount=$total_price;
            $price=$orderss['Order_orderhistory']['price'];
            $taxitem=$this->Order_tax->find('all',array('conditions'=>array('Order_tax.orderhistory_id'=>$order_id,'Order_tax.reference_id'=>$reference_id,'Order_tax.product_id'=>$product_id,'Order_tax.status !='=>0)));
            foreach($taxitem as $item){
                $id=$item['Order_tax']['id'];
                $tax_percentage=$item['Order_tax']['tax_percentage'];
                $quantity=$item['Order_tax']['quantity']-1;
                $taxamount=round($price*$quantity,2);
                $taxvalue=round((($price*$quantity*$tax_percentage)/100),2);
                
                $this->Order_tax->query("UPDATE order_tax SET quantity=$quantity,taxable_price = '$taxamount',tax_value='$taxvalue',sync=0,local_sync=0 WHERE id = '$id'");
            }
            
            
            $response['status']= true;
            $response['message']= "Quantity Decreased Successfully..!";

        
        }else{
            $response['status']= false;
            $response['message']= "Quantity must be greater then 1 or Order item not found..!";

        }
        
        
        return json_encode($response);
    }
    
    public function table_clear()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>2)));
//      print_r($tables);exit;;
        if(empty($tables))
        {   
            $response= array('status'=> false,
                'message'=> "Table not found"
            );
            return json_encode($response);
        }
        
        $checkref=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.status !='=>0)));
        if(!empty($checkref))
        {   
            $response= array('status'=> false,
                'message'=> "Please clear the item first"
            );
            return json_encode($response);
        }
        
        $tablestatus = $this->Order_table->find('first', array('conditions'=>array('reference_id'=>$ref_id,'is_takeaway'=>1)));
        if(!empty($tablestatus))
        {   
            $this->Order_table->query("update order_tables set status=0,sync=0,local_sync=0 WHERE reference_id = '$ref_id'");
        }else{
            $this->Order_table->query("update order_tables set customer_name='',customer_phone='',customer_address='',customer_pax=1,status=1,sync=0,local_sync=0 where reference_id='$ref_id'");
        }
        
        $response= array('status'=> true,
            'message'=> "Table Cleared"
        );
        return json_encode($response);
    }


    public function table_list()
    {
        $cashierid = $_REQUEST['id'];
        $todayDate = date('Y-m-d'); // ensure correct format
                
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        if(isset($_REQUEST['status'])){
            $tbles = $this->Order_table->find('all', array('conditions'=>array('status'=>$_REQUEST['status'],'is_takeaway'=>0),    'order' => array('Order_table.id' => 'ASC')
            ));
        }else{
            $tbles = $this->Order_table->find('all', array('conditions'=>array('status !='=>0,'is_takeaway'=>0),
                'order' => array('Order_table.id' => 'ASC')
    ));
        }
        if(empty($tbles))
        {
            $response =array(
                'status'=> false,
                'message'=> "Tables Not found ",
            );
            return json_encode($response);
        }else{
            $open_table_amount = 0;
            $item = array();
            
            foreach($tbles as $tble){
                $sc=0;
                $disc=0;
                $tablereference_id=$tble['Order_table']['reference_id'];
                
                $tableid=$tble['Order_table']['id'];
                $mergetablecheck = $this->Order_table_tracking->query("SELECT GROUP_CONCAT(main_table_number) as main_table_id FROM `order_table_tracking` WHERE merged_table_id='$tableid' and status=1");
                $main_table_id = $mergetablecheck[0][0]['main_table_id'] ?? '';
                
                $tablereference_id = [$tablereference_id]; // convert initial ref id to array
                
                $mergetablecheckamount = $this->Order_table_tracking->find('all', [
                    'conditions' => [
                        'Order_table_tracking.main_table_ref_id' => $tablereference_id[0],
                        'Order_table_tracking.status' => 1,
                        "DATE(Order_table_tracking.created) =" => $todayDate
                    ]
                ]);
                
                if (!empty($mergetablecheckamount)) {
                    foreach ($mergetablecheckamount as $merge) {
                        $tablereference_id[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
                    }
                }
                // $tablereference_id = "'" . implode("','", $tablereference_id) . "'";
                
                $orderdata=$this->ordercomputewithdiscounttemp($tablereference_id,$cashierid,$sc,$disc);
                
                $totalservicechg=$orderdata['totalservicechg'] ?? 0;
                $totalprice=$orderdata['totalprice'] ?? 0;
                $totaltax=$orderdata['totaltax'] ?? 0;
                $totaldiscount=$orderdata['totaldiscount'] ?? 0;
                $amount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
                
                if ($tble['Order_table']['status'] == 2) {
                    $open_table_amount += $amount;
                }

                $item[]=array(
                    'id' => $tble['Order_table']['number'],
                    'number' =>  $tble['Order_table']['number'],
                    'reference_id' =>  $tble['Order_table']['reference_id'],
                    'amount' =>  isset($amount) ? (string)$amount : "0",
                    'is_alert' =>  $tble['Order_table']['is_alert'],
                    'is_waiter_required' =>  $tble['Order_table']['is_waiter_required'],
                    'is_customer_detail_required' =>  $tble['Order_table']['is_customer_detail_required']?$tble['Order_table']['is_customer_detail_required']:"0",
                    'status' =>  $tble['Order_table']['status'],
                    'is_takeaway' =>  $tble['Order_table']['is_takeaway'],
                    'merge_with' =>  $main_table_id
                );
                
            }
            usort($item, function ($a, $b) {
                return strnatcmp($a['number'], $b['number']);
            });
            $response= array('status'=> true,
                'message'=> "success",
                'tables'=>$item,
                'open_table_amount'=>number_format($open_table_amount,2)
            );
        }
        return json_encode($response);
    }

    public function table_unbill()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id)));
        if(empty($txnchk))
        {   
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }else{
            $tableid=$txnchk['Order_transaction']['table_number'];
            
            $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.number'=>$tableid,'Order_table.reference_id'=>$ref_id,'Order_table.status !='=>0)));
//          print_r($tables);exit;;
            
            $orderdata=$this->ordercompute($ref_id,$cashierid,0,0);
            
            // $this->Order_transaction->id=$txnchk['Order_transaction']['id'];
            // // if($this->Order_transaction->delete()){
            // $update = [
            //     'Order_transaction' => [
            //         'reference_id' =>$ref_id,
            //         'status' => 0
            //     ]
            // ];
            
            $updateData = [
                'Order_transaction.status' => 0
            ];
            
            $updated = $this->Order_transaction->updateAll(
                $updateData,
                ['Order_transaction.reference_id' => $ref_id]
            );
            
            $this->Order_transaction->updateAll(
                array(
                    'Order_transaction.sync' => 0,
                    'Order_transaction.local_sync' => 0
                ),
                array(
                    'Order_transaction.reference_id' => $ref_id
                )
            );

            if ($updated) {
            
                if ($tables) {
                    $this->Order_table->updateAll(
                        array(
                            'Order_table.status'     => 2,
                            'Order_table.sync'       => 0,
                            'Order_table.local_sync' => 0
                        ),
                        array(
                            'Order_table.id' => (int)$tables['Order_table']['id']
                        )
                    );
                }
            
                $response = [
                    'status' => true,
                    'message' => "Bill updated"
                ];
                return json_encode($response);
            
            } else {
            
                $response = [
                    'status' => false,
                    'message' => "Bill not updated"
                ];
                return json_encode($response);
            }

            
        }
        
        
    }
    
    public function table_billupdate_discount()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $disc=$_REQUEST['discount'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        
        $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
        if(empty($tables)){
            $response['status']= false;
            $response['message']= "Table is not in billing state";
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        if($txnchk['Order_transaction']['servicecharge']>0){
            $sc=1;
        }else{
            $sc=0;
        }
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='1',`discount_type_value`='$disc',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    public function table_billupdate_servicecharge()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $sc=$_REQUEST['service_charge'];
        
        $disc=0;
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($sc==''){
            $response =array(
                'status'=> false,
                'message'=> "Service Charge Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
        if(empty($tables)){
            $response['status']= false;
            $response['message']= "Table is not in billing state";
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='1',`discount_type_value`='$disc',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    public function table_billupdate_coupon()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $coupon=$_REQUEST['coupon'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($coupon==''){
            $response =array(
                'status'=> false,
                'message'=> "Coupon Code Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$coupon,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
        if(empty($coup))
        {
            $response =array(
                'status'=> false,
                'message'=> "Coupon not found Or Coupon Expired",
            );
            return json_encode($response);
        }
        $coup_value=$coup['Coupon']['value'];
        
        $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
        if(empty($tables)){
            $response['status']= false;
            $response['message']= "Table is not in billing state";
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        if($txnchk['Order_transaction']['servicecharge']>0){
            $sc=1;
        }else{
            $sc=0;
        }
        
        $disc=$coup_value;
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
//      print_r($ref_id.'<br>'.$cashierid.'<br>'.$sc.'<br>'.$disc);exit;
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='0',`discount_type_value`='$coupon',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
        
    public function table_bill_coupon_removed()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        $coup_value=0;
        
        $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
        if(empty($tables)){
            $response['status']= false;
            $response['message']= "Table is not in billing state";
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        if($txnchk['Order_transaction']['servicecharge']>0){
            $sc=1;
        }else{
            $sc=0;
        }
        
        $disc=$coup_value;
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Removed",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Removed",
            );
            return json_encode($response);
        }
    }
    
    public function ordercompute($txnid = null, $user_id = null, $is_sc = 1, $discount = 0)
    {
        $response = ['status' => false];
    
        if (empty($txnid)) {
            return $response;
        }
    
        $sc = ($is_sc == 1) ? servicecharge : 0;
    
        /* -------------------------------------------------
         * STEP 1: ORDER TOTALS
         * ------------------------------------------------- */
    
        $priceq = "(Order_orderhistory.total_price - Order_orderhistory.discount)";
        $discq  = "($priceq * $discount / 100)";
        $scq    = "(($priceq - $discq) * $sc / 100)";
        $taxq   = "(($priceq - $discq + $scq) * (Order_orderhistory.total_tax_percentage / 100))";
    
        $this->Order_orderhistory->virtualFields = [
            'tprice'      => "SUM($priceq)",
            'tdisc'       => "SUM($discq)",
            'tservicechg' => "SUM($scq)",
            'total_tax'   => "SUM($taxq)"
        ];
    
        $summary = $this->Order_orderhistory->find('first', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $txnid,
                'Order_orderhistory.status !='    => 0
            ],
            'fields' => ['reference_id', 'tprice', 'tdisc', 'tservicechg', 'total_tax'],
            'recursive' => -1
        ]);
    
        if (empty($summary['Order_orderhistory']['reference_id'])) {
            return $response;
        }
    
        $response['status']         = true;
        $response['totalprice']     = round($summary['Order_orderhistory']['tprice'], 2);
        $response['totaldiscount']  = round($summary['Order_orderhistory']['tdisc'], 2);
        $response['totalservicechg']= round($summary['Order_orderhistory']['tservicechg'], 2);
        $response['totaltax']       = round($summary['Order_orderhistory']['total_tax'], 2);
    
        /* -------------------------------------------------
         * STEP 2: ITEM LEVEL TAX UPDATE
         * ------------------------------------------------- */
    
        $priceq = "(Order_orderhistory.price - Order_orderhistory.discount)";
        $discq  = "($priceq * $discount / 100)";
        $scq    = "(($priceq - $discq) * $sc / 100)";
        $tamountq = "($priceq - $discq + $scq)";
    
        $this->Order_orderhistory->virtualFields = [
            'tamount' => $tamountq
        ];
    
        $items = $this->Order_orderhistory->find('all', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $txnid,
                'Order_orderhistory.status !='    => 0
            ],
            'fields' => ['id', 'product_id', 'price', 'tamount'],
            'recursive' => -1
        ]);
    
        foreach ($items as $row) {
    
            $orderhistory_id = $row['Order_orderhistory']['id'];
            $product_id      = $row['Order_orderhistory']['product_id'];
            $tamount         = round($row['Order_orderhistory']['tamount'], 2);
    
            $taxItems = $this->Order_tax->find('all', [
                'conditions' => [
                    'Order_tax.reference_id'     => $txnid,
                    'Order_tax.orderhistory_id' => $orderhistory_id,
                    'Order_tax.product_id'      => $product_id,
                    'Order_tax.status !='       => 0
                ],
                'recursive' => -1
            ]);
    
            foreach ($taxItems as $taxRow) {
    
                $tax = $taxRow['Order_tax'];
    
                $taxable_price = round($tamount * $tax['quantity'], 2);
                $tax_value     = round(($taxable_price * $tax['tax_percentage']) / 100, 2);
    
                try {
                    $this->Order_tax->updateAll(
                        [
                            'Order_tax.taxable_price'       => $taxable_price,
                            'Order_tax.tax_value'           => $tax_value,
                            'Order_tax.discount_percentage' => $discount,
                            'Order_tax.sync'                => 0,
                            'Order_tax.local_sync'          => 0
                        ],
                        [
                            'Order_tax.id' => $tax['id']
                        ]
                    );
                    
                    $db = $this->Order_tax->getDataSource();
                    if ($db->lastError()) {
                        $this->trackUser($txnid, $user_id, 'order_tax_update_sql_error', [
                            'tax_id' => $tax['id'],
                            'error'  => $db->lastError()
                        ]);
                    }
                } catch (Exception $e) {
                    $this->trackUser($txnid, $user_id, 'order_tax_update_exception', [
                        'tax_id' => $tax['id'],
                        'error'  => $e->getMessage()
                    ]);
                }
            }
        }
    
        return $response;
    }

    public function wallet_report_print()
    {
        $cashierid = $_REQUEST['id'];
        $sdate = $_REQUEST['sdate'];
        $edate = $_REQUEST['edate'];
        
        $response = array();
        
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        if($sdate==''){
            $response =array(
                'status'=> false,
                'message'=> "Start date Missing",
            );
            return json_encode($response);
        }
        
        if($edate==''){
            $response =array(
                'status'=> false,
                'message'=> "End date Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $cashiernames=$this->User->find('first',array('conditions'=>array('User.id'=>$cashierid)));
        $cashiername=$cashiernames['User']['name'];
        
        $shiftstart = shiftstart;
        $shiftend   = shiftend;
        
        // Make sure to handle shift crossing midnight
        $startDatetime = $sdate . ' ' . $shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($edate . ' +1 day')) . ' ' . $shiftend;
        // $edate = new DateTime($edate);
        // $edate = $edate->modify('+1 day')->format('Y-m-d');

        $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'];
        
        $key = array();
        $value = array();
        
        $key[] = "Card Data";
        $value[] = "------";
        $key[] = "Active Cards";
        $value[] = round($activecards,2);
        $key[] = "Inactive Cards";
        $value[] = round($inactivecards,2);
        
        $key[] = "Wallet Data";
        $value[] = "------";
        $key[] = "Total Balance Added";
        $value[] = round($totaladded,2);
        $key[] = "Total Used Amount";
        $value[] = round($totalused,2);
        $key[] = "Total Refunded Amount";
        $value[] = round($totalrefund,2);
        $key[] = "Total Security Amount";
        $value[] = round($totalsecurity,2);
        $key[] = "Net Balance";
        $value[] = round(($totaladded-$totalused),2);
        
        $newData = array();

        $newData[] = array(
            "key" => "Card Data",
            "value" => "------",
            "heading" => true
        );
        
       // Add the rest of the elements dynamically
        for ($i = 1; $i < count($key); $i++) {
            $newData[] = array(
                "key" => $key[$i],
                "value" => (string)$value[$i],
                "heading" => $key[$i] === "Wallet Data"
            );
        }
        
        $response = array(
            'status' => true,
            'message' => "success",
            'data' => $newData
        );
        
        return json_encode($response, JSON_PRETTY_PRINT);
    }
    
    public function item_sale_list()
    {
        $cashierid = $_REQUEST['id'];
        $sdate = $_REQUEST['sdate'];
        $edate = $_REQUEST['edate'];
        
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($sdate==''){
            $response =array(
                'status'=> false,
                'message'=> "Start date Missing",
            );
            return json_encode($response);
        }
        
        if($edate==''){
            $response =array(
                'status'=> false,
                'message'=> "End date Missing",
            );
            return json_encode($response);
        }
        
        // Shift datetime range
        $startDatetime = $sdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($edate . ' +1 day')) . ' ' . shiftend;
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $shiftstart=shiftstart;
        $shiftend=shiftend;
        // $edate = new DateTime($edate);
        // $edate = $edate->modify('+1 day')->format('Y-m-d');

        $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 cashier_id=$cashierid GROUP BY product_id");
        foreach ($orderhistories as $orderhistory) {
            $items[] = [
                'product_id' => $orderhistory['order_orderhistories']['product_id'],
                'product_name' => $orderhistory['order_orderhistories']['product_name'],
                'category_name' => $orderhistory['order_orderhistories']['category_name'],
                'quantity' => $orderhistory[0]['totalquantity'],
                'price' => $orderhistory['order_orderhistories']['price']
            ];
        }

        $response= array('status'=> true,
                'message'=> "success",
                'data'=>$items
            );
        return json_encode($response);
    }
    
    public function item_sale_report()
    {
        $cashierid = $_REQUEST['id'];
        $sdate = $_REQUEST['sdate'];
        $edate = $_REQUEST['edate'];
        
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($sdate==''){
            $response =array(
                'status'=> false,
                'message'=> "Start date Missing",
            );
            return json_encode($response);
        }
        
        if($edate==''){
            $response =array(
                'status'=> false,
                'message'=> "End date Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $key = array();
        $value = array();
        // $shiftstart=shiftstart;
        // $shiftend=shiftend;
        
        // Build shift datetime range
        $startDatetime = $sdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($edate . ' +1 day')) . ' ' . shiftend;
    
        $orderhistories = $this->Order_orderhistory->query("SELECT product_id,product_name,category_name,SUM(quantity) as totalquantity,price,total_price,SUM(price*quantity)/SUM(quantity) AS final_price  FROM `order_orderhistories` WHERE status=2 and created between '$startDatetime' and '$endDatetime'  GROUP BY product_id");
        foreach ($orderhistories as $orderhistory) {
            $key[] = $orderhistory[0]['totalquantity'].' * '.$orderhistory['order_orderhistories']['product_name'];
            $value[] = $orderhistory[0]['final_price']*$orderhistory[0]['totalquantity'];
        }
        $newData = array();
        for ($i = 0; $i < count($key); $i++) {
            
            $newData[] = array(
                "key" => $key[$i],
                "value" => (string)$value[$i]
            );
        }    
    
        $response = array(
            'status' => true,
            'message' => "success",
            'data' => $newData
        );
        
        return json_encode($response, JSON_PRETTY_PRINT);
    }
    
    public function card_validity_options()
    {
        $cashierid = $_REQUEST['id'];
    
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        $items[] = [
            'name'=>'today',
            'value'=>$todayDate
        ];
        $items[] = [
            'name'=>'unlimited',
            'value'=>'2030-12-31'
        ];
        $items[] = [
            'name'=>'custom',
            'value'=>'custom'
        ];
        
        $response= array('status'=> true,
                'message'=> "success",
                'data'=>$items
            );
        return json_encode($response);
    }
    
    public function card_payment_options()
    {
        $cashierid = $_REQUEST['id'];
    
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $items[] = [
            'name'=>'cash'
        ];
        $items[] = [
            'name'=>'card'
        ];
        $items[] = [
            'name'=>'online'
        ];
        
        $response= array('status'=> true,
                'message'=> "success",
                'data'=>$items
            );
        return json_encode($response);
    }
    
    public function quick_billupdate_discount()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $disc=$_REQUEST['discount'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.cashier_id'=>$cashierid,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid, 'Order_transaction.status !='=>0)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        if($txnchk['Order_transaction']['servicecharge']>0){
            $sc=1;
        }else{
            $sc=0;
        }
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='1',`discount_type_value`='$disc',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    public function quick_billupdate_servicecharge()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $sc=$_REQUEST['service_charge'];
        
        $disc=0;
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($sc==''){
            $response =array(
                'status'=> false,
                'message'=> "Service Charge Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid, 'Order_transaction.status !='=>0)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='1',`discount_type_value`='$disc',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    public function quick_billupdate_coupon()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        $coupon=$_REQUEST['coupon'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($coupon==''){
            $response =array(
                'status'=> false,
                'message'=> "Coupon Code Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$coupon,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
        if(empty($coup))
        {
            $response =array(
                'status'=> false,
                'message'=> "Coupon not found Or Coupon Expired",
            );
            return json_encode($response);
        }
        $coup_value=$coup['Coupon']['value'];
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid, 'Order_transaction.status !='=>0)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        if($txnchk['Order_transaction']['servicecharge']>0){
            $sc=1;
        }else{
            $sc=0;
        }
        
        $disc=$coup_value;
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
//      print_r($ref_id.'<br>'.$cashierid.'<br>'.$sc.'<br>'.$disc);exit;
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='0',`discount_type_value`='$coupon',`amount`='$totalamount',`createtime`='$createtime',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    //validity crons
    public function cron_disable_cards()
    {
        // Current date and time
        $today= date('Y-m-d H:i:s');
        
        $cards = $this->Card->query("SELECT * FROM `cards` WHERE status=2");
        foreach($cards as $card) {
            $cardnumber = $card['cards']['cardnumber'];
            $cardtracks = $this->Cardtracking->query("SELECT newbalance FROM `cardtracking` WHERE cardnumber='$cardnumber' order by id desc limit 1");
            if($cardtracks[0]['cardtracking']['newbalance']){
                
                do {
                    $txnid = '';
                    for ($i = 0; $i < 10; $i++) {
                        $txnid .= rand(0, 9);
                    }
                    $existingOTP = $this->Cardtracking->find('first', array(
                        'conditions' => array(
                            'txnid' => $txnid
                        )
                    ));
                } while ($existingOTP); // Continue generating OTP until it doesn't exist
                
                $data['Cardtracking']=array(
                    'cardnumber'=>$cardnumber,
                    'txnid'=>$txnid,
                    'purpose'=>'transfertoTheParkWallet',
                    'oldbalance'=>$cardtracks[0]['cardtracking']['newbalance'],
                    'amount'=>$cardtracks[0]['cardtracking']['newbalance'],
                    'newbalance'=>0,
                    'type'=>5,
                    'payment_mode'=>'transfertoTheParkWallet'
                );
              
                if($this->Cardtracking->saveAll($data['Cardtracking']))
                {
                    $this->Card->query("UPDATE cards SET cardbalance = 0,status=1,name='',mobile=0,email='',sync=0,local_sync=0,valid_to=NULL WHERE cardnumber = '$cardnumber'");
                }else{
                    echo "Not Saved";
                }
            }else{
                $this->Card->query("UPDATE cards SET cardbalance = 0,status=1,name='',mobile=0,email='',sync=0,local_sync=0,valid_to=NULL WHERE cardnumber = '$cardnumber'");
            }
        }
    }
    
    public function payment_storecard()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $amount = $_REQUEST['amount'];
        $otp = $_REQUEST['otp'];
        $mode = $_REQUEST['mode'];
        $reference_id = $_REQUEST['reference_id'];
        $device_id = $_REQUEST['device_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($amount==''){
            $response =array(
                'status'=> false,
                'message'=> "Amount Missing",
            );
            return json_encode($response);
        }
        if($mode==''){
            $response =array(
                'status'=> false,
                'message'=> "payment mode Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status'=>1)));
        if(empty($transactions))
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not found",
            );
            return json_encode($response);
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card Deactivated",
            );
            return json_encode($response);
        }else{
            $pinreq=$card['Card']['pin_required'];
            if($pinreq){
                if($otp==''){
                    $response =array(
                        'status'=> false,
                        'message'=> "PIN Missing",
                    );
                    return json_encode($response);
                }
                $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.pin'=>$otp,'Card.status'=>2)));
                if(empty($card))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Wrong PIN ",
                    );
                    return json_encode($response);
                }
            }
            $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.cardbalance >= '=>$amount)));
            if(empty($card))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdrawal Amount not exist in card ",
                );
                return json_encode($response);
            }
            
            $today = date("Y-m-d H:i:s");
            $currentDate = new DateTime($today);
            $newdate = $currentDate->modify('-2 minute')->format('Y-m-d H:i:s');

            $cardtrackingchk = $this->Cardtracking->query("SELECT * FROM cardtracking where cardnumber='$cardno' and amount='$amount' and created between '$newdate' and '$today' and type=2");
            if(!empty($cardtrackingchk))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdraw blocked for 2 minutes",
                );
                return json_encode($response);
            }
            
            $name=$card['Card']['name'];
            $mobile=$card['Card']['mobile'];
            $oldbal=$card['Card']['cardbalance'];
            $newbal=$oldbal-$amount;
            
            do {
                $txnid = '';
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existingOTP = $this->Cardtracking->find('first', array(
                    'conditions' => array(
                        'txnid' => $txnid
                    )
                ));
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $data['Cardtracking']=array(
                'cardnumber'=>$cardno,
                'cashierID'=>$cashierid,
                'txnid'=>$txnid,
                'reference_id'=>$reference_id,
                'cashierName'=>$cashiername,
                'customername'=>$name,
                'customerphone'=>$mobile,
                'purpose'=>'withdrawal',
                'oldbalance'=>$oldbal,
                'amount'=>$amount,
                'newbalance'=>$newbal,
                'type'=>2,
                'payment_mode'=>$mode
            );
          
            if($this->Cardtracking->saveAll($data['Cardtracking']))
            {
                $this->Card->query("UPDATE cards SET cardbalance = $newbal,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            
                //payment save
            
                $datas['Order_payment']=array(
                    'reference_id'=>$reference_id,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'type'=>8,
                    'type_value'=>'StoreCard',
                    'amount'=>$amount,
                    'remarks'=>$cardno
                );
                if($this->Order_payment->saveAll($datas['Order_payment']))
                {
                    $finalpayment=0;
                    $finalamount=0;
                    $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id'");
                    if($allpayments){
                        $finalpayment=$allpayments[0][0]['pay_amount'];
                    }
                    if($transactions){
                        $finalamount=$transactions['Order_transaction']['amount'];
                    }
                    $amount_diff=$finalamount-$finalpayment;
                    if($amount_diff<1){
                        
                        $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                        $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='StoreCard',sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                        
                        $stockupdate=$this->stock_update($reference_id);
                        if(!$stockupdate){
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                            $response['full_payment']= true; 
                        }
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= true;
                        
                    }else{
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= false;
                    }            
                }else{
                    $response['status']= false;
                    $response['message']= "Payment Data not saved Error:102";
                    $response['full_payment']= false;
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "failed",
                );
            }
        }
        return json_encode($response);
    }
    
    public function payment_storecard_table()
    {
        $cashierid = $_REQUEST['id'];
        $cardno=preg_replace('/\D/', '', $_REQUEST['cardno']);
        $amount = $_REQUEST['amount'];
        $otp = $_REQUEST['otp'];
        $mode = $_REQUEST['mode'];
        $reference_id = $_REQUEST['reference_id'];
        $device_id = $_REQUEST['device_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($cardno==''){
            $response =array(
                'status'=> false,
                'message'=> "Card no Missing",
            );
            return json_encode($response);
        }
        if($amount==''){
            $response =array(
                'status'=> false,
                'message'=> "Amount Missing",
            );
            return json_encode($response);
        }
        if($mode==''){
            $response =array(
                'status'=> false,
                'message'=> "payment mode Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found or User Deactivated",
            );
            return json_encode($response);
        }else{
            $cashiername=$users['User']['name'];
        }
        
        $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status'=>1)));
        if(empty($transactions))
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not found",
            );
            return json_encode($response);
        }
        
        $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.status'=>2)));
        if(empty($card))
        {
            $response =array(
                'status'=> false,
                'message'=> "Card not found or Card Deactivated",
            );
            return json_encode($response);
        }else{
            $pinreq=$card['Card']['pin_required'];
            if($pinreq){
                if($otp==''){
                    $response =array(
                        'status'=> false,
                        'message'=> "PIN Missing",
                    );
                    return json_encode($response);
                }
                $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.pin'=>$otp,'Card.status'=>2)));
                if(empty($card))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Wrong PIN ",
                    );
                    return json_encode($response);
                }
            }
            $card = $this->Card->find('first', array('conditions'=>array('Card.cardnumber'=>$cardno,'Card.cardbalance >= '=>$amount)));
            if(empty($card))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdrawal Amount not exist in card ",
                );
                return json_encode($response);
            }
            
            $today = date("Y-m-d H:i:s");
            $currentDate = new DateTime($today);
            $newdate = $currentDate->modify('-2 minute')->format('Y-m-d H:i:s');

            $cardtrackingchk = $this->Cardtracking->query("SELECT * FROM cardtracking where cardnumber='$cardno' and amount='$amount' and created between '$newdate' and '$today' and type=2");
            if(!empty($cardtrackingchk))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "Withdraw blocked for 2 minutes",
                );
                return json_encode($response);
            }
            
            $name=$card['Card']['name'];
            $mobile=$card['Card']['mobile'];
            $oldbal=$card['Card']['cardbalance'];
            $newbal=$oldbal-$amount;
            
            do {
                $txnid = '';
                for ($i = 0; $i < 10; $i++) {
                    $txnid .= rand(0, 9);
                }
                $existingOTP = $this->Cardtracking->find('first', array(
                    'conditions' => array(
                        'txnid' => $txnid
                    )
                ));
            } while ($existingOTP); // Continue generating OTP until it doesn't exist
            
            $data['Cardtracking']=array(
                'cardnumber'=>$cardno,
                'cashierID'=>$cashierid,
                'txnid'=>$txnid,
                'reference_id'=>$reference_id,
                'cashierName'=>$cashiername,
                'customername'=>$name,
                'customerphone'=>$mobile,
                'purpose'=>'withdrawal',
                'oldbalance'=>$oldbal,
                'amount'=>$amount,
                'newbalance'=>$newbal,
                'type'=>2,
                'payment_mode'=>$mode
            );
          
            if($this->Cardtracking->saveAll($data['Cardtracking']))
            {
                $this->Card->query("UPDATE cards SET cardbalance = $newbal,sync=0,local_sync=0 WHERE cardnumber = '$cardno'");
            
                //payment save
            
                $datas['Order_payment']=array(
                    'reference_id'=>$reference_id,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'type'=>8,
                    'type_value'=>'StoreCard',
                    'amount'=>$amount,
                    'remarks'=>$cardno
                );
                if($this->Order_payment->saveAll($datas['Order_payment']))
                {
                    $finalpayment=0;
                    $finalamount=0;
                    $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id'");
                    if($allpayments){
                        $finalpayment=$allpayments[0][0]['pay_amount'];
                    }
                    if($transactions){
                        $finalamount=$transactions['Order_transaction']['amount'];
                    }
                    $amount_diff=$finalamount-$finalpayment;
                    if($amount_diff<1){
                           
                        $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                        $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='StoreCard',sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
                        
                        $tablestatus = $this->Order_table->find('first', array('conditions'=>array('reference_id'=>$reference_id,'is_takeaway'=>1)));
                        if(!empty($tablestatus))
                        {   
                            $this->Order_table->query("UPDATE order_tables set status=0,sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        }else{
                            $this->Order_table->query("UPDATE order_tables SET customer_name='',customer_phone='',customer_address='',customer_pax=1,status = 1,reference_id='$pin',sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                        }
                        
                        $stockupdate=$this->stock_update($reference_id);
                        if(!$stockupdate){
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                            $response['full_payment']= true; 
                        }
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= true;
                        
                    }else{
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= false;
                    }            
                }else{
                    $response['status']= false;
                    $response['message']= "Payment Data not saved Error:102";
                    $response['full_payment']= false;
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "failed",
                );
            }
        }
        return json_encode($response);
    }
    
    //booking cron
    public function cron_booking_alarm()
    {
        // Current date and time
        $today= date('Y-m-d H:i:s');
        // $today = '2024-07-29 11:00:00';
        $addDatetime = new DateTime($today);
        $addDatetime->modify("+30 minutes");
        $checkTime = $addDatetime->format('Y-m-d H:i:s');
        
        
        $upcomingBookings =  $this->Online_booking->query("SELECT * FROM `online_bookings` WHERE booking_time between '$today' and '$checkTime' AND status=1 LIMIT 10");
        foreach($upcomingBookings as $upcomingBooking) {
            $tableNumber = $upcomingBooking['online_bookings']['table_number'];
            $tableCheck = $this->Order_table->query("SELECT * FROM `order_tables` WHERE number='$tableNumber' AND status!=1");
            if($tableCheck) {
                $this->Order_table->query("UPDATE order_tables SET is_alert = '1',sync=0,local_sync=0 WHERE number = '$tableNumber'");
            }else{
                $this->Order_table->query("UPDATE order_tables SET is_alert = '0',sync=0,local_sync=0 WHERE number = '$tableNumber'");
            }
        }
        
        $addtime = new DateTime($today);
        $addtime->modify("-5 minutes");
        $check_time = $addtime->format('Y-m-d H:i:s');
        $Bookingupdates = $this->Online_booking->query("SELECT * FROM `online_bookings` WHERE booking_time between '$check_time' and '$today' AND status=1");
        foreach($Bookingupdates as $Bookingupdate) {
            $tableNumber = $Bookingupdate['online_bookings']['table_number'];
            $id = $Bookingupdate['online_bookings']['id'];
            $payment_type = $Bookingupdate['online_bookings']['payment_type'];
            if($payment_type==2){
                $pay_option = $Bookingupdate['online_bookings']['pay_option'];
                $pay_option_value = $Bookingupdate['online_bookings']['pay_option_value'];
            }else{
                $pay_option=1;
                $pay_option_value='postpaid';
            }
            
            $tableCheck = $this->Order_table->query("SELECT * FROM `order_tables` WHERE number='$tableNumber' AND status=1");
            if($tableCheck) {
                $datas['Order_payment']=array(
                    'reference_id'=>$tableCheck[0]['order_tables']['reference_id'],
                    'cashier_id'=>$Bookingupdate['online_bookings']['user_id'],
                    'type'=>$pay_option,
                    'type_value'=>$pay_option_value,
                    'amount'=>$Bookingupdate['online_bookings']['cover_charge'],
                    'remarks'=>$Bookingupdate['online_bookings']['remarks'],
                    'status'=>2
                );
                if($this->Order_payment->saveAll($datas['Order_payment']))
                {
                    $this->Order_table->query("UPDATE order_tables SET status = '2',modified='$today',sync=0,local_sync=0 WHERE number = '$tableNumber'");
                    $this->Online_booking->query("UPDATE online_bookings SET status = '3',modified='$today',sync=0,local_sync=0 WHERE id = '$id'");
                }
            }
        }
        
    }
    
    //stock update from POS
    public function stock_update($txnid=null){
        $response['status']=false;
        
        $orderhistories=$this->Order_orderhistory->find('all',array('conditions'=>array('Order_orderhistory.reference_id'=>$txnid,'status' =>2)));
        foreach($orderhistories as $data){
            $product_id=$data['Order_orderhistory']['product_id'];
            $product_quantity=$data['Order_orderhistory']['quantity'];
            $cashier_id=$data['Order_orderhistory']['cashier_id'];
            
            $store=$this->User->find('first',array('conditions'=>array('User.id'=>$cashier_id,'status' =>1)));
            $store_id=$store['User']['location_id'];
            
            //product linking with semifinished 
            // $semifinished_products=$this->Inventory_product_semifinished_linking->find('all',array('conditions'=>array('product_id'=>$product_id,'status' =>1)));
            $semifinished_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Product','parent_id'=>$product_id,'component_type'=>'Semifinished','status' =>1)));
            foreach($semifinished_products as $semifinished_product){
                $semifinished_id=$semifinished_product['Inventory_linking']['component_id'];
                $semiquantity=$semifinished_product['Inventory_linking']['quantity']*$product_quantity;
                
                $semidetails=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semifinished_id)));
                $semiprice=$semidetails['Inventory_semifinished']['price'];
                
                   
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => ['sku_id' => $semifinished_product['Inventory_linking']['component_id'],'store_id' =>$store_id,'type'=>'OUTLET','item_type'=>'semifinished' ],
                        '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-$semiquantity;
                    
                    $ledgerData['Stock_ledger'] = [
                            'store_id'        => $store_id,
                            'sku_id'          => $semifinished_product['Inventory_linking']['component_id'],
                            'sku_name'        => $semifinished_product['Inventory_linking']['component_name'],
                            'sku_price'       => $semiprice,
                            'unit_id'         => $semifinished_product['Inventory_linking']['component_unit'],
                            'unit_name'       => $semifinished_product['Inventory_linking']['component_unit_name'],
                            'record_id'       => $txnid,
                            'record_type'     => 'stockout',
                            'quantity'        => $semiquantity,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'debit',
                            'type'            => 'OUTLET',
                            'item_type'       => 'semifinished',
                            'created'         => date('Y-m-d H:i:s')
                    ];
                    if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                        $check=false;
                    }
                    
                    
                    //semifinished linking with sku
                    $sku_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Semifinished','parent_id'=>$semifinished_id,'component_type'=>'Sku','status' =>1)));
                    foreach($sku_products as $sku_product){
                        $sku_id=$sku_product['Inventory_linking']['component_id'];
                        $skuquantity=$sku_product['Inventory_linking']['quantity']*$semiquantity;
                        
                        $skudetails=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                        $skuprice=$skudetails['Inventory_sku']['price'];
                        
                        
                            $ledgerprevdetails = $this->Stock_ledger->find('first', [
                                'conditions' => ['sku_id' => $sku_product['Inventory_linking']['component_id'],'store_id' =>$store_id ,'type' =>'OUTLET','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-$skuquantity;
                            
                            $ledgerData['Stock_ledger'] = [
                                    'store_id'        => $store_id,
                                    'sku_id'          => $sku_product['Inventory_linking']['component_id'],
                                    'sku_name'        => $sku_product['Inventory_linking']['component_name'],
                                    'sku_price'       => $skuprice,
                                    'unit_id'         => $sku_product['Inventory_linking']['component_unit'],
                                    'unit_name'       => $sku_product['Inventory_linking']['component_unit_name'],
                                    'record_id'       => $txnid,
                                    'record_type'     => 'stockout',
                                    'quantity'        => $skuquantity,
                                    'balance_stock'   => $newQuantity,
                                    'actual_balance'  => $newQuantity,
                                    'quantity_type'   => 'debit',
                                    'type'            => 'OUTLET',
                                    'item_type'       => 'SKU',
                                    'created'         => date('Y-m-d H:i:s')
                            ];
                            if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                                $check=false;
                            }
                            $check=true;
                        
                    }
                    
                    
                    //semifinished linking with semifinished
                    $linked_semi_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Semifinished','parent_id'=>$semifinished_id,'component_type'=>'Semifinished','status' =>1)));
                    foreach($linked_semi_products as $linked_semi_product){
                        $linked_semi_id=$linked_semi_product['Inventory_linking']['component_id'];
                        $linked_semi_quantity=$linked_semi_product['Inventory_linking']['quantity']*$semiquantity;
                        
                        $linkedsemidetails=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$linked_semi_id)));
                        $linkedsemiprice=$linkedsemidetails['Inventory_semifinished']['price'];
                        
                            $ledgerprevdetails = $this->Stock_ledger->find('first', [
                                'conditions' => ['sku_id' => $linked_semi_id,'store_id' =>$store_id ,'type' =>'OUTLET','item_type'=>'Semifinished' ],
                                '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-$skuquantity;
                            
                            $ledgerData['Stock_ledger'] = [
                                    'store_id'        => $store_id,
                                    'sku_id'          => $linked_semi_id,
                                    'sku_name'        => $linkedsemidetails['Inventory_semifinished']['name'],
                                    'sku_price'       => $linkedsemiprice,
                                    'unit_id'         => $linkedsemidetails['Inventory_semifinished']['unit'],
                                    'unit_name'       => $linkedsemidetails['Inventory_semifinished']['unit_name'],
                                    'record_id'       => $txnid,
                                    'record_type'     => 'stockout',
                                    'quantity'        => $linked_semi_quantity,
                                    'balance_stock'   => $newQuantity,
                                    'actual_balance'  => $newQuantity,
                                    'quantity_type'   => 'debit',
                                    'type'            => 'OUTLET',
                                    'item_type'       => 'Semifinished',
                                    'created'         => date('Y-m-d H:i:s')
                            ];
                            if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                                $check=false;
                            }
                            $check=true;
                        
                    }
                    
            }
            
            //product linking with direct sku 
            $sku_direct_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Product','parent_id'=>$product_id,'component_type'=>'Sku','status' =>1)));
            foreach($sku_direct_products as $sku_direct_product){
                $sku_id=$sku_direct_product['Inventory_linking']['component_id'];
                //sku previous stock
                $skudirectquantity=$sku_direct_product['Inventory_linking']['quantity']*$product_quantity;
                $skudetails=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                $skuprice=$skudetails['Inventory_sku']['price'];
                
                    
                    $ledgerprevdetails = $this->Stock_ledger->find('first', [
                        'conditions' => ['sku_id' => $sku_id,'store_id' =>$store_id ,'type' =>'OUTLET','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-$skudirectquantity;
                    
                    $ledgerData['Stock_ledger'] = [
                            'store_id'        => $store_id,
                            'sku_id'          => $sku_direct_product['Inventory_linking']['component_id'],
                            'sku_name'        => $sku_direct_product['Inventory_linking']['component_name'],
                            'sku_price'       => $skuprice,
                            'unit_id'         => $sku_direct_product['Inventory_linking']['component_unit'],
                            'unit_name'       => $sku_direct_product['Inventory_linking']['component_unit_name'],
                            'record_id'       => $txnid,
                            'record_type'     => 'stockout',
                            'quantity'        => $skudirectquantity,
                            'balance_stock'   => $newQuantity,
                            'actual_balance'  => $newQuantity,
                            'quantity_type'   => 'debit',
                            'type'            => 'OUTLET',
                            'item_type'       => 'SKU',
                            'created'         => date('Y-m-d H:i:s')
                    ];
                    if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                        $check=false;
                    }
                    $check=true;
                
            }
            
            //modifier linking with products 
            $ordermodifiers=$this->Order_modifier->find('all',array('conditions'=>array('reference_id'=>$txnid,'product_id'=>$product_id,'status' =>1)));
            foreach($ordermodifiers as $modifier){
                $modifier_id=$modifier['Order_modifier']['modifier_id'];
                $quantity=$modifier['Order_modifier']['quantity'];
                
                //modifier linking with semifinished 
                $semifinished_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Modifier','parent_id'=>$modifier_id,'component_type'=>'Semifinished','status' =>1)));
                foreach($semifinished_products as $semifinished_product){
                    $semifinished_id=$semifinished_product['Inventory_linking']['component_id'];
                    $semiquantity=$semifinished_product['Inventory_linking']['quantity']*$quantity;
                    
                    $semidetails=$this->Inventory_semifinished->find('first',array('conditions'=>array('id'=>$semifinished_id)));
                    $semiprice=$semidetails['Inventory_semifinished']['price'];
                    
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $semifinished_id,'store_id' =>$store_id,'type'=>'OUTLET','item_type'=>'semifinished' ],
                            '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-$semiquantity;
                        
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $store_id,
                                'sku_id'          => $semifinished_id,
                                'sku_name'        => $semifinished_product['Inventory_linking']['component_name'],
                                'sku_price'       => $semiprice,
                                'unit_id'         => $semifinished_product['Inventory_linking']['component_unit'],
                                'unit_name'       => $semifinished_product['Inventory_linking']['component_unit_name'],
                                'record_id'       => $txnid,
                                'record_type'     => 'stockout_modifier',
                                'quantity'        => $semiquantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'type'            => 'OUTLET',
                                'item_type'       => 'semifinished',
                                'created'         => date('Y-m-d H:i:s')
                        ];
                        if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                            $check=false;
                        }
                        
                        //semifinished linking with sku
                        $sku_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Semifinished','parent_id'=>$semifinished_id,'component_type'=>'Sku','status' =>1)));
                        foreach($sku_products as $sku_product){
                            $sku_id=$sku_product['Inventory_linking']['component_id'];
                            $skuquantity=$sku_product['Inventory_linking']['quantity']*$semiquantity;
                            
                            $skudetails=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                            $skuprice=$skudetails['Inventory_sku']['price'];
                            
                                $ledgerprevdetails = $this->Stock_ledger->find('first', [
                                    'conditions' => ['sku_id' => $sku_id,'store_id' =>$store_id ,'type' =>'OUTLET','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-$skuquantity;
                                
                                $ledgerData['Stock_ledger'] = [
                                        'store_id'        => $store_id,
                                        'sku_id'          => $sku_id,
                                        'sku_name'        => $sku_product['Inventory_linking']['component_name'],
                                        'sku_price'       => $skuprice,
                                        'unit_id'         => $sku_product['Inventory_linking']['component_unit'],
                                        'unit_name'       => $sku_product['Inventory_linking']['component_unit_name'],
                                        'record_id'       => $txnid,
                                        'record_type'     => 'stockout_modifier',
                                        'quantity'        => $skuquantity,
                                        'balance_stock'   => $newQuantity,
                                        'actual_balance'  => $newQuantity,
                                        'quantity_type'   => 'debit',
                                        'type'            => 'OUTLET',
                                        'item_type'       => 'SKU',
                                        'created'         => date('Y-m-d H:i:s')
                                ];
                                if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                                    $check=false;
                                }
                                $check=true;
                            
                        }
                    
                }
                
                //modifier linking with direct sku 
                $sku_direct_products=$this->Inventory_linking->find('all',array('conditions'=>array('parent_type'=>'Modifier','parent_id'=>$modifier_id,'component_type'=>'Sku','status' =>1)));
                foreach($sku_direct_products as $sku_direct_product){
                    $sku_id=$sku_direct_product['Inventory_linking']['component_id'];
                    //sku previous stock
                    $skudirectquantity=$sku_direct_product['Inventory_linking']['quantity']*$quantity;
                    $skudetails=$this->Inventory_sku->find('first',array('conditions'=>array('id'=>$sku_id)));
                    $skuprice=$skudetails['Inventory_sku']['price'];
                    
                        
                        $ledgerprevdetails = $this->Stock_ledger->find('first', [
                            'conditions' => ['sku_id' => $sku_id,'store_id' =>$store_id ,'type' =>'OUTLET' ,'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-$skudirectquantity;
                        
                        $ledgerData['Stock_ledger'] = [
                                'store_id'        => $store_id,
                                'sku_id'          => $sku_direct_product['Inventory_linking']['component_id'],
                                'sku_name'        => $sku_direct_product['Inventory_linking']['component_name'],
                                'sku_price'       => $skuprice,
                                'unit_id'         => $sku_direct_product['Inventory_linking']['component_unit'],
                                'unit_name'       => $sku_direct_product['Inventory_linking']['component_unit_name'],
                                'record_id'       => $txnid,
                                'record_type'     => 'stockout_modifier',
                                'quantity'        => $skudirectquantity,
                                'balance_stock'   => $newQuantity,
                                'actual_balance'  => $newQuantity,
                                'quantity_type'   => 'debit',
                                'type'            => 'OUTLET',
                                'item_type'       => 'SKU',
                                'created'         => date('Y-m-d H:i:s')
                        ];
                        if(!$this->Stock_ledger->saveAll($ledgerData['Stock_ledger'])){
                            $check=false;
                        }
                        $check=true;
                
                }
                
            }
        }
        if($check){
            $response['status']=true;
        }
        return $response;
    }
    
    public function waiter_list()
    {
        $cashierid = $_REQUEST['id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $waiters = $this->Order_waiter->find('all', array('conditions'=>array('status'=>1)));
    
        if(empty($waiters))
        {
            $response =array(
                'status'=> false,
                'message'=> "Waiters Not found",
            );
            return json_encode($response);
        }else{
            foreach($waiters as $waiter){
                
                $item[]=array(
                    'id' => $waiter['Order_waiter']['id'],
                    'name' =>  $waiter['Order_waiter']['name'],
                    'phone' =>  $waiter['Order_waiter']['phone'],
                    'pin_number' =>  $waiter['Order_waiter']['pin_number'],
                    'is_pin_required' =>  $waiter['Order_waiter']['is_pin_required'],
                    'status' =>  $waiter['Order_waiter']['status'],
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'waiters'=>$item
            );
        }
        return json_encode($response);
    }
    
    public function assign_waiter()
    {
        $response = array();
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['table_reference_id'];
        $waiter_id = $_REQUEST['waiter_id'];
        
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        if($waiter_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Waiter Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $waiters = $this->Order_waiter->find('first', array('conditions'=>array('id'=>$waiter_id,'status'=>1)));
        if(empty($waiters))
        {
            $response =array(
                'status'=> false,
                'message'=> "Waiter Not found",
            );
            return json_encode($response);
        }
        $waiter_name = $waiters['Order_waiter']['name'];
        
        $tables = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$reference_id,'Order_table.status'=>1)));
        if(empty($tables))
        {
            $response =array(
                'status'=> false,
                'message'=> "Table Not found or not vacant",
            );
            return json_encode($response);
        }    
        
        $this->Order_table->query("UPDATE order_tables SET waiter_id = '$waiter_id',waiter_name='$waiter_name',sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
            
        $response= array('status'=> true,
            'message'=> "success",
        );
    
        return json_encode($response);
    }
    
    public function ordercomputewithdiscount($txnid=null,$user_id=null,$is_sc=1,$discount=0)
    {
        $response['status']=false;
        $totalservicechg=0;
        $totalprice=0;
        $totaltax1=0;
        $totaltax2=0;
        $totaldiscount=0;
        $sc=0;
        if($is_sc==1){
            $sc=servicecharge;
        }
        $discq="(((Order_orderhistory.total_price)-(Order_orderhistory.discount))*$discount/100)";
        $priceq="((Order_orderhistory.total_price)-(Order_orderhistory.discount))";
    
        $this->Order_orderhistory->virtualFields = array('tdisc'=>"SUM($discq)",'tservicechg'=>"SUM(($priceq-$discq)*($sc/100))",'tprice'=>"SUM($priceq)",'total_tax'=>"SUM(($priceq+(($priceq-$discq)*($sc/100))-$discq)*((Order_orderhistory.total_tax_percentage)/100))");  
        
        $orderhistories=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.reference_id'=>$txnid,'Order_orderhistory.status !=' =>0),'fields'=>array('tdisc','Order_orderhistory.reference_id','tprice','total_tax','tservicechg')));
        
        if(!empty($orderhistories['Order_orderhistory']['reference_id'])){
            $response['status']=true;
            $totalservicechg=round($orderhistories['Order_orderhistory']['tservicechg'],2);
            $totalprice=round($orderhistories['Order_orderhistory']['tprice'],2);
            $totaltax=round($orderhistories['Order_orderhistory']['total_tax'],2);
            $totaldiscount=round($orderhistories['Order_orderhistory']['tdisc'],2);
            
            //tax update
            $discq="(((Order_orderhistory.price)-(Order_orderhistory.discount))*$discount/100)";
            $priceq="((Order_orderhistory.price)-(Order_orderhistory.discount))";
            
            $taxes=[];
            
            $this->Order_orderhistory->virtualFields = array('tamount'=>"($priceq+(($priceq-$discq)*($sc/100))-$discq)");  
            $neworderhistories=$this->Order_orderhistory->find('all',array('conditions'=>array('Order_orderhistory.reference_id'=>$txnid,'Order_orderhistory.cashier_id'=>$user_id,'Order_orderhistory.status !=' =>0),'fields'=>array('Order_orderhistory.reference_id','tamount','product_id','price')));
            foreach($neworderhistories as $data){
                $reference_id=$data['Order_orderhistory']['reference_id'];
                $product_id=$data['Order_orderhistory']['product_id'];
                $tamount=$data['Order_orderhistory']['tamount'];
                $price=$data['Order_orderhistory']['price'];
                
                
                $taxitem=$this->Order_tax->find('all',array('conditions'=>array('Order_tax.reference_id'=>$txnid,'Order_tax.product_id'=>$product_id,'Order_tax.status !=' =>0)));
                foreach($taxitem as $item){
                    $id=$item['Order_tax']['id'];
                    $tax_id=$item['Order_tax']['tax_id'];
                    $tax_percentage=$item['Order_tax']['tax_percentage'];
                    $quantity=$item['Order_tax']['quantity'];
                    $taxamount=round($tamount*$quantity,2);
                    $taxvalue=round((($tamount*$quantity*$tax_percentage)/100),2);
                    
                    if (isset($taxes[$tax_id])) {
                        $taxes[$tax_id]['tax_value'] += round($taxvalue, 2);
                    } else {
                        // Add new entry if tax_id doesn't exist
                        $taxes[$tax_id] = array(
                            'id' => $id,
                            'tax_id' =>  $item['Order_tax']['tax_id'],
                            'tax_name' => $item['Order_tax']['tax_name'],
                            'tax_percentage' => $tax_percentage,
                            'tax_value' => round($taxvalue, 2)
                        );
                    }
                }
            }
            
            $response['totalservicechg']=$totalservicechg;
            $response['totalprice']=$totalprice;
            $response['totaltax']=$totaltax;
            $response['totaldiscount']=$totaldiscount;
            $response['taxes']=$taxes;
        }
        // print_r($response);exit;
        return $response;
    }
    
    public function billupdate_discount()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id=$_REQUEST['reference_id'];
        $disc=$_REQUEST['discount'];
        $sc = $_REQUEST['service_charge'];
        $device_id = $_REQUEST['device_id'];
        $type = $_REQUEST['type'];
        $table = $_REQUEST['table'];
        $discount_type_value=$disc;
        
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        
        
        if($sc==''){
            $response =array(
                'status'=> false,
                'message'=> "Service Charge Missing",
            );
            return json_encode($response);
        }
        
        if($device_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Device Id Missing",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$disc,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
                if(empty($coup))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Coupon not found Or Coupon Expired",
                    );
                    return json_encode($response);
                }
                $disc=$coup['Coupon']['value'];
            }else{
                $disc=0;
            }
        }
        
        if($type==1){
            $disc=$disc;
        }
        
        if($type==2){
            $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id='$ref_id'");
            if($subtotals){
                $subtotal=$subtotals[0][0]['subtotal'];
                if($subtotal){
                    $disc=(($disc*100)/$subtotal);
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    );
                    return json_encode($response);
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Bill Not Found",
                );
                return json_encode($response);
            }
        }
        
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $packagechk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.package'=>1,'Order_orderhistory.status !='=>0)));
        if(empty($packagechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "You can not Merge Discount with package.",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.cashier_id'=>$cashierid,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        
        if($table){
            $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
            if(empty($tables)){
                $response['status']= false;
                $response['message']= "Table is not in billing state";
                return json_encode($response);
            }
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid , 'Order_transaction.status !='=>0)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        
        $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='$type',`discount_type_value`='$discount_type_value',`amount`='$totalamount',`createtime`='$createtime',`name`='$name',`phone`='$phone',`address`='$address',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    
    public function sync_data()
    {
        $cashierid = $_REQUEST['id'];
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        // -------------------------------
        // Fire Cron PULL ASYNC (non-blocking)
        // -------------------------------
        //$cronUrl = Router::url('/Cron/pull_data', true);
        if (!empty($cashierid)) {
            $cronUrl = Router::url("/Cron/pull_data/$cashierid", true);
        } else {
            $cronUrl = Router::url("/Cron/pull_data", true);
        }
        
		$ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $cronUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1);      // important
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
        curl_exec($ch);
        curl_close($ch);
			
		// -------------------------------
        // Fire Cron PUSH ASYNC (non-blocking)
        // -------------------------------
        //$cronUrl = Router::url('/Cron/pull_data', true);
        if (!empty($cashierid)) {
            $cronUrlpush = Router::url("/Cron/push_data/$cashierid", true);
        } else {
            $cronUrlpush = Router::url("/Cron/push_data", true);
        }
		

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $cronUrlpush);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 1);      // important
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
        curl_exec($ch);
        curl_close($ch);
        
        $catitem=[];
        $locations = $this->User_location->query("
            SELECT location_id,id,location_name
            FROM `user_locations` 
            WHERE user_id=$cashierid AND status=1
        ");
        $all_locations=[];
        $item=[];
        foreach($locations as $location){
            $location_ids = $location['user_locations']['location_id'];
            
            $branchcategoreis = $this->Catalog_category_branches->find('all', array(
                'conditions' => array(
                    'Catalog_category_branches.location_id' => $location_ids,
                    'Catalog_category_branches.status' => 1
                )
            ));
        
            if(!empty($branchcategoreis)){
                foreach($branchcategoreis as $bracnhcategorei){
                    $branchcat_id=$bracnhcategorei['Catalog_category_branches']['category_id'];
                    $subitem=[];
                    
                    $categoreis = $this->Catalog_category->find('all', array('conditions'=>array('Catalog_category.status'=>1,'id'=>$branchcat_id)));
                    foreach($categoreis as $categorei){
                        $cat_id=$categorei['Catalog_category']['id'];
                    
                        if($categorei['Catalog_category']['is_subcategory']){
                            $subcats = $this->Catalog_subcategory->find('all', array('conditions'=>array('Catalog_subcategory.cat_id'=>$cat_id,'status'=>1)));
                            foreach($subcats as $subcat){
                                
                                $subitem[]=array(
                                    'id' => $subcat['Catalog_subcategory']['id'],
                                    'name' =>  $subcat['Catalog_subcategory']['name'],
                                    'food_type' =>  $subcat['Catalog_subcategory']['food_type'],
                                    'image'=>'',
                                    'created' =>  $subcat['Catalog_subcategory']['created']
                                );
                                
                                $branchproducts = $this->Catalog_product_branches->find('all', array('conditions'=>array('Catalog_product_branches.location_id' => $location_ids,'Catalog_product_branches.status'=>1)));
                                if(!empty($branchproducts))
                                {
                                    foreach($branchproducts as $branchproduct){
                                        $branchproduct_id=$branchproduct['Catalog_product_branches']['product_id'];
                                    
                                        $products = $this->Catalog_product->find('all', array('conditions'=>array('id'=>$branchproduct_id,'status'=>1,'subcat_id'=>$subcat['Catalog_subcategory']['id'])));
                                        if(!empty($products))
                                        {
                                            foreach($products as $product){
                                                $taxesitems=[];
                                                $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                                                foreach($taxess as $tax){
                                                    $taxesitems[]=array(
                                                        'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                                        'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                                        'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                                    );
                                                }
                                                
                                                $groupmodifier_items = [];
                                                
                                                $modifierss = $this->Inventory_linking->find('all', [
                                                    'conditions' => [
                                                        'Inventory_linking.parent_id' => $product['Catalog_product']['id'],
                                                        'Inventory_linking.parent_type' => 'Product',
                                                        'Inventory_linking.component_type' => 'Modifier_group',
                                                        'Inventory_linking.status' => 1
                                                    ],
                                                    'joins' => [
                                                        [
                                                            'table' => 'catalog_modifier_group',
                                                            'alias' => 'Catalog_modifier_group',
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'Catalog_modifier_group.id = Inventory_linking.component_id',
                                                                'Catalog_modifier_group.status' => 1
                                                            ]
                                                        ],
                                                        [
                                                            'table' => 'inventory_linking',
                                                            'alias' => 'IL2', // Second-level linking
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'IL2.parent_id = Catalog_modifier_group.id',
                                                                'IL2.parent_type' => 'Modifier_group',
                                                                'IL2.component_type' => 'Modifier',
                                                                'IL2.status' => 1
                                                            ]
                                                        ],
                                                        [
                                                            'table' => 'catalog_modifier',
                                                            'alias' => 'Catalog_modifier',
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'Catalog_modifier.id = IL2.component_id',
                                                                'Catalog_modifier.status' => 1
                                                            ]
                                                        ]
                                                    ],
                                                    'fields' => [
                                                        'Inventory_linking.id',
                                                        'Inventory_linking.component_id',
                                                        'Inventory_linking.component_name',
                                                        'Inventory_linking.created',
                                                
                                                        'Catalog_modifier_group.id',
                                                        'Catalog_modifier_group.name',
                                                        'Catalog_modifier_group.description',
                                                        'Catalog_modifier_group.group_type',
                                                        'Catalog_modifier_group.sort_order',
                                                        'Catalog_modifier_group.is_default',
                                                        'Catalog_modifier_group.min',
                                                        'Catalog_modifier_group.max',
                                                
                                                        'IL2.id',
                                                        'IL2.component_id',
                                                        'IL2.component_name',
                                                
                                                        'Catalog_modifier.id',
                                                        'Catalog_modifier.name',
                                                        'Catalog_modifier.description',
                                                        'Catalog_modifier.food_type',
                                                        'Catalog_modifier.sort_order',
                                                        'Catalog_modifier.price',
                                                        'Catalog_modifier.weight'
                                                    ],
                                                    'recursive' => -1
                                                ]);
                
                                                $groupMap = [];
                                                
                                                foreach ($modifierss as $mod_item) {
                                                    $groupId = $mod_item['Inventory_linking']['component_id'];
                                                
                                                    // Initialize group if not already present
                                                    if (!isset($groupMap[$groupId])) {
                                                        $groupMap[$groupId] = [
                                                            'id' => $mod_item['Inventory_linking']['id'],
                                                            'modifier_group_id' => $groupId,
                                                            'modifier_group_name' => $mod_item['Inventory_linking']['component_name'],
                                                            'group_type' => $mod_item['Catalog_modifier_group']['group_type'],
                                                            'sort_order' => $mod_item['Catalog_modifier_group']['sort_order'],
                                                            'is_default' => $mod_item['Catalog_modifier_group']['is_default'],
                                                            'min' => $mod_item['Catalog_modifier_group']['min'],
                                                            'max' => $mod_item['Catalog_modifier_group']['max'],
                                                            'description' => $mod_item['Catalog_modifier_group']['description'],
                                                            'created' => $mod_item['Inventory_linking']['created'],
                                                            'modifiers' => []
                                                        ];
                                                    }
                                                
                                                    // Only push modifier if exists
                                                    if (!empty($mod_item['Catalog_modifier']['id'])) {
                                                        // $foodType = $mod_item['Catalog_modifier']['food_type'] == 1 ? 'Non-Veg' : 'Veg';
                                                
                                                        $modifierData = [
                                                            'id' => $mod_item['Catalog_modifier']['id'],
                                                            'name' => $mod_item['Catalog_modifier']['name'],
                                                            'modifier_name' => $mod_item['IL2']['component_name'],
                                                            'food_type' => $mod_item['Catalog_modifier']['food_type'],
                                                            'sort_order' => $mod_item['Catalog_modifier']['sort_order'],
                                                            'price' => $mod_item['Catalog_modifier']['price'],
                                                            'weight' => $mod_item['Catalog_modifier']['weight'],
                                                            'description' => $mod_item['Catalog_modifier']['description'],
                                                        ];
                                                
                                                        $groupMap[$groupId]['modifiers'][] = $modifierData;
                                                    }
                                                }
                                                // Final group array
                                                $groupmodifier_items = array_values($groupMap);
                                            
                                                if($product['Catalog_product']['image']){
                                                    $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                                                }else{
                                                    $imgpth=''; 
                                                }        
                                                // print_r($imgpth);exit;
                                                
                                                $product_id=$product['Catalog_product']['id'];
                                                $todayDate = date("Y-m-d");
                                                
                                                $is_offer='0';
                                                $offer_id='';
                                                $offer_name='';
                                                $offer_type='';
                                                $start_date='';
                                                $start_time='';
                                                $end_date='';
                                                $end_time='';
                                                
                                                $offers = $this->Offer->query("SELECT *
                                                    FROM pos_offers
                                                    WHERE status = 1
                                                      AND sku_id = $product_id
                                                      AND start_date <= '$todayDate'
                                                      AND end_date >= '$todayDate' order by id desc LIMIT 1 ");
                                                      
                                                if($offers[0]['pos_offers']['offer_id']){
                                                    $is_offer='1';
                                                    $offer_id=$offers[0]['pos_offers']['offer_id'];
                                                    $offer_name=$offers[0]['pos_offers']['name'];
                                                    $offer_type=$offers[0]['pos_offers']['offer_type'];
                                                    $start_date=$offers[0]['pos_offers']['start_date'];
                                                    $start_time=$offers[0]['pos_offers']['start_time'];
                                                    $end_date=$offers[0]['pos_offers']['end_date'];
                                                    $end_time=$offers[0]['pos_offers']['end_time'];
                                                }
                                                
                                                $item[]=array(
                                                    'id' => $product['Catalog_product']['id'],
                                                    'name' =>  $product['Catalog_product']['name'],
                                                    'cat_id' =>  $product['Catalog_product']['cat_id'],
                                                    'cat_name' =>  $product['Catalog_product']['cat_name'],
                                                    'subcat_id' =>  $product['Catalog_product']['subcat_id'],
                                                    'subcat_name' =>  $product['Catalog_product']['subcat_name'],
                                                    'description' => $product['Catalog_product']['description'],
                                                    'food_type' =>  $product['Catalog_product']['food_type'],
                                                    'sort_order' =>  $product['Catalog_product']['sort_order'],
                                                    'recommended' =>  $product['Catalog_product']['recommended'],
                                                    'variation' =>  $product['Catalog_product']['variation'],
                                                    'price' => $branchproduct['Catalog_product_branches']['price'],
                                                    'kds' => $product['Catalog_product']['kds'],
                                                    'markup_price' =>  $product['Catalog_product']['markup_price'],
                                                    'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                                    'weight' =>  $product['Catalog_product']['weight'],
                                                    'serves_people' =>  $product['Catalog_product']['serves_people'],
                                                    'type' =>  $product['Catalog_product']['type'],
                                                    'image' => $imgpth,
                                                    'taxes'=>$taxesitems,
                                                    'modifier_group'=>$groupmodifier_items,
                                                    'status' =>  $product['Catalog_product']['status'],
                                                    'created' =>  $product['Catalog_product']['created'],
                                                    'store_id' => $location_ids,
                                                    'is_offer' =>  $is_offer,
                                                    'offer_id' =>  $offer_id ?? '',
                                                    'offer_name' =>  $offer_name ?? '',
                                                    'offer_type' =>  $offer_type ?? '',
                                                    'start_date' =>  $start_date ?? '',
                                                    'start_time' =>  $start_time ?? '',
                                                    'end_date' =>  $end_date ?? '',
                                                    'end_time' =>  $end_time ?? ''
                                                );
                                            }
                                        }
                                    }
                                }
                            }
                            $catitem[]=array(
                                'id' => $categorei['Catalog_category']['id'],
                                'name' =>  $categorei['Catalog_category']['name'],
                                'food_type' =>  $categorei['Catalog_category']['food_type'],
                                'is_subcategory' =>  $categorei['Catalog_category']['is_subcategory'],
                                'type' =>  $categorei['Catalog_category']['type'],
                                'subcategory'=>$subitem,
                                'image'=>'',
                                'created' =>  $categorei['Catalog_category']['created'],
                                'store_id' => $location_ids
                            );
                        }else{
                 
                            $catitem[]=array(
                                'id' => $categorei['Catalog_category']['id'],
                                'name' =>  $categorei['Catalog_category']['name'],
                                'food_type' =>  $categorei['Catalog_category']['food_type'],
                                'is_subcategory' =>  $categorei['Catalog_category']['is_subcategory'],
                                'type' =>  $categorei['Catalog_category']['type'],
                                'subcategory'=>$subitem,
                                'image'=>'',
                                'created' =>  $categorei['Catalog_category']['created'],
                                'store_id' => $location_ids
                            );
                            
                            $branchproducts = $this->Catalog_product_branches->find('all', array('conditions'=>array('Catalog_product_branches.location_id' => $location_ids,'Catalog_product_branches.status'=>1)));
                            if(!empty($branchproducts))
                            {
                                foreach($branchproducts as $branchproduct){
                                    $branchproduct_id=$branchproduct['Catalog_product_branches']['product_id'];
                            
                                    $products = $this->Catalog_product->find('all', array('conditions'=>array('Catalog_product.id'=>$branchproduct_id,'Catalog_product.status'=>1,'Catalog_product.cat_id'=>$cat_id)));
                                    if(!empty($products))
                                    {
                                        foreach($products as $product){
                                            $taxesitems=[];
                                            $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                                            foreach($taxess as $tax){
                                                $taxesitems[]=array(
                                                    'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                                    'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                                    'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                                );
                                            }
                                        
                                        
                                            $groupmodifier_items = [];
                                            
                                            $modifierss = $this->Inventory_linking->find('all', [
                                                'conditions' => [
                                                    'Inventory_linking.parent_id' => $product['Catalog_product']['id'],
                                                    'Inventory_linking.parent_type' => 'Product',
                                                    'Inventory_linking.component_type' => 'Modifier_group',
                                                    'Inventory_linking.status' => 1
                                                ],
                                                'joins' => [
                                                    [
                                                        'table' => 'catalog_modifier_group',
                                                        'alias' => 'Catalog_modifier_group',
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'Catalog_modifier_group.id = Inventory_linking.component_id',
                                                            'Catalog_modifier_group.status' => 1
                                                        ]
                                                    ],
                                                    [
                                                        'table' => 'inventory_linking',
                                                        'alias' => 'IL2', // Second-level linking
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'IL2.parent_id = Catalog_modifier_group.id',
                                                            'IL2.parent_type' => 'Modifier_group',
                                                            'IL2.component_type' => 'Modifier',
                                                            'IL2.status' => 1
                                                        ]
                                                    ],
                                                    [
                                                        'table' => 'catalog_modifier',
                                                        'alias' => 'Catalog_modifier',
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'Catalog_modifier.id = IL2.component_id',
                                                            'Catalog_modifier.status' => 1
                                                        ]
                                                    ]
                                                ],
                                                'fields' => [
                                                    'Inventory_linking.id',
                                                    'Inventory_linking.component_id',
                                                    'Inventory_linking.component_name',
                                                    'Inventory_linking.created',
                                            
                                                    'Catalog_modifier_group.id',
                                                    'Catalog_modifier_group.name',
                                                    'Catalog_modifier_group.description',
                                                    'Catalog_modifier_group.group_type',
                                                    'Catalog_modifier_group.sort_order',
                                                    'Catalog_modifier_group.is_default',
                                                    'Catalog_modifier_group.min',
                                                    'Catalog_modifier_group.max',
                                            
                                                    'IL2.id',
                                                    'IL2.component_id',
                                                    'IL2.component_name',
                                            
                                                    'Catalog_modifier.id',
                                                    'Catalog_modifier.name',
                                                    'Catalog_modifier.description',
                                                    'Catalog_modifier.food_type',
                                                    'Catalog_modifier.sort_order',
                                                    'Catalog_modifier.price',
                                                    'Catalog_modifier.weight'
                                                ],
                                                'recursive' => -1
                                            ]);
                                            
                                            $groupMap = [];
                                            
                                            foreach ($modifierss as $mod_item) {
                                                $groupId = $mod_item['Inventory_linking']['component_id'];
                                                
                                                // Initialize group if not already present
                                                if (!isset($groupMap[$groupId])) {
                                                    $groupMap[$groupId] = [
                                                        'id' => $mod_item['Inventory_linking']['id'],
                                                        'modifier_group_id' => $groupId,
                                                        'modifier_group_name' => $mod_item['Inventory_linking']['component_name'],
                                                        'group_type' => $mod_item['Catalog_modifier_group']['group_type'],
                                                        'sort_order' => $mod_item['Catalog_modifier_group']['sort_order'],
                                                        'is_default' => $mod_item['Catalog_modifier_group']['is_default'],
                                                        'description' => $mod_item['Catalog_modifier_group']['description'],
                                                        'min' => $mod_item['Catalog_modifier_group']['min'],
                                                        'max' => $mod_item['Catalog_modifier_group']['max'],
                                                        'created' => $mod_item['Inventory_linking']['created'],
                                                        'modifiers' => []
                                                    ];
                                                }
                                            
                                                // Only push modifier if exists
                                                if (!empty($mod_item['Catalog_modifier']['id'])) {
                                                    $foodType = $mod_item['Catalog_modifier']['food_type'] == 1 ? 'Non-Veg' : 'Veg';
                                            
                                                    $modifierData = [
                                                        'id' => $mod_item['Catalog_modifier']['id'],
                                                        'name' => $mod_item['Catalog_modifier']['name'],
                                                        'modifier_name' => $mod_item['IL2']['component_name'],
                                                        'food_type' => $mod_item['Catalog_modifier']['food_type'],
                                                        'sort_order' => $mod_item['Catalog_modifier']['sort_order'],
                                                        'price' => $mod_item['Catalog_modifier']['price'],
                                                        'weight' => $mod_item['Catalog_modifier']['weight'],
                                                        'description' => $mod_item['Catalog_modifier']['description'],
                                                    ];
                                            
                                                    $groupMap[$groupId]['modifiers'][] = $modifierData;
                                                }
                                            }
                                            
                                            // Final group array
                                            $groupmodifier_items = array_values($groupMap);
                
                                            
                                            if($product['Catalog_product']['image']){
                                                $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                                            }else{
                                                $imgpth=''; 
                                            } 
                                            
                                            $product_id=$product['Catalog_product']['id'];
                                            $todayDate = date("Y-m-d");
                                            
                                            $is_offer='0';
                                            $offer_id='';
                                            $offer_name='';
                                            $offer_type='';
                                            $start_date='';
                                            $start_time='';
                                            $end_date='';
                                            $end_time='';
                                            
                                            $offers = $this->Offer->query("SELECT *
                                                FROM pos_offers
                                                WHERE status = 1
                                                  AND sku_id = $product_id
                                                  AND start_date <= '$todayDate'
                                                  AND end_date >= '$todayDate' order by id desc LIMIT 1 ");
                                                  
                                            if($offers[0]['pos_offers']['offer_id']){
                                                $is_offer='1';
                                                $offer_id=$offers[0]['pos_offers']['offer_id'];
                                                $offer_name=$offers[0]['pos_offers']['name'];
                                                $offer_type=$offers[0]['pos_offers']['offer_type'];
                                                $start_date=$offers[0]['pos_offers']['start_date'];
                                                $start_time=$offers[0]['pos_offers']['start_time'];
                                                $end_date=$offers[0]['pos_offers']['end_date'];
                                                $end_time=$offers[0]['pos_offers']['end_time'];
                                            }
                                            
                                            
                                            $item[]=array(
                                                'id' => $product['Catalog_product']['id'],
                                                'name' =>  $product['Catalog_product']['name'],
                                                'cat_id' =>  $product['Catalog_product']['cat_id'],
                                                'cat_name' =>  $product['Catalog_product']['cat_name'],
                                                'subcat_id' =>  '',
                                                'subcat_name' =>  '',
                                                'description' => $product['Catalog_product']['description'],
                                                'food_type' =>  $product['Catalog_product']['food_type'],
                                                'sort_order' =>  $product['Catalog_product']['sort_order'],
                                                'recommended' =>  $product['Catalog_product']['recommended'],
                                                'variation' =>  $product['Catalog_product']['variation'],
                                                'price' =>$branchproduct['Catalog_product_branches']['price'],
                                                'kds' => $product['Catalog_product']['kds'],
                                                'markup_price' =>  $product['Catalog_product']['markup_price'],
                                                'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                                'weight' =>  $product['Catalog_product']['weight'],
                                                'serves_people' =>  $product['Catalog_product']['serves_people'],
                                                'type' =>  $product['Catalog_product']['type'],
                                                'image' => $imgpth,
                                                'taxes'=>$taxesitems,
                                                'modifier_group'=>$groupmodifier_items,
                                                'status' =>  $product['Catalog_product']['status'],
                                                'created' =>  $product['Catalog_product']['created'],
                                                'store_id' => $location_ids,
                                                'is_offer' =>  strval($is_offer),
                                                'offer_id' =>  $offer_id ?? '',
                                                'offer_name' =>  $offer_name ?? '',
                                                'offer_type' =>  $offer_type ?? '',
                                                'start_date' =>  $start_date ?? '',
                                                'start_time' =>  $start_time ?? '',
                                                'end_date' =>  $end_date ?? '',
                                                'end_time' =>  $end_time ?? ''
                                            );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            $all_locations[]=array(
                'id' => $location['user_locations']['id'],
                'location_id' =>  $location['user_locations']['location_id'],
                'location_name' =>  $location['user_locations']['location_name']
            );
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        //dish type
        $dishitems=[];
        $dishes = $this->Catalog_product->query("SELECT dish_type FROM `catalog_product` WHERE status=1 group by dish_type");
        if(!empty($dishes))
        {
            foreach($dishes as $dish){
                if($dish['catalog_product']['dish_type']==0){
                    $dish_name='Food';
                }elseif($dish['catalog_product']['dish_type']==1){
                    $dish_name='Beverage';
                }elseif($dish['catalog_product']['dish_type']==2){
                    $dish_name='Liquor';
                }else{
                    $dish_name='Other';
                }
                $dishitems[]=array(
                    'id' => $dish['catalog_product']['dish_type'],
                    'store_id' =>  $dish['catalog_product']['dish_type'],
                    'name' =>  $dish_name,
                    'kds' =>  $dish['catalog_product']['dish_type'],
                    'ip' =>  $dish['catalog_product']['dish_type'],
                    'status' =>  1
                );
            }
        }
        
        $todayDate = date("Y-m-d");
        $carditems[] = [
            'name'=>'today',
            'value'=>$todayDate
        ];
        $carditems[] = [
            'name'=>'unlimited',
            'value'=>'2030-12-31'
        ];
        $carditems[] = [
            'name'=>'custom',
            'value'=>'custom'
        ];
        
        $paymentitems[] = [
            'name'=>'cash'
        ];
        $paymentitems[] = [
            'name'=>'card'
        ];
        $paymentitems[] = [
            'name'=>'online'
        ];
        
        $response= array('status'=> true,
            'message'=> "success",
            'products'=>$item,
            'category'=>$catitem,
            'printers'=>$printeritems,
            'dishes'=>$dishitems,
            'card_validity'=>$carditems,
            'payment_options'=>$paymentitems,
            'all_locations'=>$all_locations
        );
        return json_encode($response);
    }
    
    public function transaction_history()
    {
        $cashierid = $_REQUEST['id'];
        
        $startdate = date("Y-m-d");
        $enddate = date("Y-m-d");
            
        if(isset($_REQUEST['from'])){
            $startdate = $_REQUEST['from'];
        }
        if(isset($_REQUEST['to'])){
            $enddate = $_REQUEST['to'];
        }
        
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "Cashier not found",
            );
            return json_encode($response);
        }
        
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('cashier_id'=>$cashierid,'status'=>2,'created BETWEEN ? AND ?' => array($startDatetime, $endDatetime)),'order' => array('Order_transaction.id' => 'DESC')));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                $store_id=$orders['Order_transaction']['store_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                $payment_mode='';
                $pay_mode = $this->Order_payment->query("SELECT GROUP_CONCAT(type_value) as payment FROM `order_payments` WHERE reference_id='$reference_id' and store_id='$store_id' and status=2");
                if(!empty($pay_mode))
                {
                    $payment_mode=$pay_mode[0][0]['payment'];
                }
                
        $orderitems=[];
        $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,SUM(quantity) as quantity,price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id='$reference_id' and store_id='$store_id' and status!=0 group BY product_id");
        if(!empty($orderss))
        {
            foreach($orderss as $items){
                if(!isset($items['order_orderhistories']['remarks'])){
                    $items['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $items['order_orderhistories']['id'],
                    'reference_id' =>  $items['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $items['order_orderhistories']['cashier_id'],
                    'group_id' =>  $items['order_orderhistories']['group_id'],
                    'category' =>  $items['order_orderhistories']['category'],
                    'category_name' =>  $items['order_orderhistories']['category_name'],
                    'kds' =>  $items['order_orderhistories']['kds'],
                    'product_id' =>  $items['order_orderhistories']['product_id'],
                    'product_name' =>  $items['order_orderhistories']['product_name'],
                    'quantity' =>  $items[0]['quantity'],
                    'price' =>  $items['order_orderhistories']['price'],
                    'total_tax' =>  $items[0]['total_tax'],
                    'total_price' =>  $items[0]['total_price'],
                    'discount' =>  $items[0]['discount'],
                    'table_number' =>  $items['order_orderhistories']['table_number'],
                    'remarks' =>  $items['order_orderhistories']['remarks'],
                    'status' =>  $items['order_orderhistories']['status'],
                    'created' =>  $items['order_orderhistories']['created']
                );
            }
        }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'created' =>  $orders['Order_transaction']['created'],
                    'payment_mode' =>$payment_mode??'',
                    'items' =>$orderitems
                );
            }
        }
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'transactions'=>$transactionitems
            );
        return json_encode($response);
    }
    
    public function transaction_detail()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.id'=>$reference_id,'Order_transaction.status'=>2)));
        if(empty($transactions))
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not billed",
            );
            return json_encode($response);
        }
        $transaction_reference_id=$transactions['Order_transaction']['reference_id'];
        $store_id=$transactions['Order_transaction']['store_id'];
        
        $orderitems=[];
        $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,SUM(quantity) as quantity,price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id='$transaction_reference_id' and store_id='$store_id' and status!=0 group BY product_id");
        if(!empty($orderss))
        {
            foreach($orderss as $orders){
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders[0]['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders[0]['total_tax'],
                    'total_price' =>  $orders[0]['total_price'],
                    'discount' =>  $orders[0]['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems
            );
        return json_encode($response);
    }
    
    
    
    public function insert_manager_track()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $id = $_REQUEST['id'];
        if($id==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $reference_id = $_REQUEST['reference_id'];
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id is Missing",
            );
            return json_encode($response);
        }
        
        $pin = $_REQUEST['pin'];
        if($pin==''){
            $response =array(
                'status'=> false,
                'message'=> "Manager PIN is Missing",
            );
            return json_encode($response);
        }
        
        $type = $_REQUEST['type'];
        $remarks = $_REQUEST['remarks'];
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$id,'User.status'=>1,'User.role'=>'cashier')));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "Cashier not found",
            );
            return json_encode($response);
        }
        $location_id=$users['User']['location_id'];
        $location_name=$users['User']['location_name'];
        
        $userpinchk = $this->User->find('first', array('conditions'=>array('User.location_id'=>$location_id,'User.status'=>1,'User.role'=>'manager','User.pin'=>$pin)));
        if(empty($userpinchk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Manager Pin not found for this location",
            );
            return json_encode($response);
        }
        $datas['User_track']=array(
            'user_id'=>$userpinchk['User']['id'],
            'reference_id'=>$reference_id,
            'location_id'=>$location_id,
            'location_name'=>$location_name,
            'type'=>$type,
            'remarks'=>$remarks
        );
        if($this->User_track->saveAll($datas['User_track']))
        {
            $response['status']= true;
            $response['message']= "Manager Track Saved Successfully..!";
        }else{
            $response['status']= false;
            $response['message']= "Manager Track not Saved..!";
        }
        return json_encode($response);
    }
    
    
    //new
    public function booked_table_list()
    {
        $cashierid = $_REQUEST['id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $tbles = $this->Order_table->find('all', array('conditions'=>array('status'=>2)));
        if(empty($tbles))
        {
            $response =array(
                'status'=> false,
                'message'=> "Tables Not found ",
            );
            return json_encode($response);
        }else{
            foreach($tbles as $tble){
                $sc=0;
                $disc=0;
                $tablereference_id=$tble['Order_table']['reference_id'];
                $item[]=array(
                    'id' => $tble['Order_table']['number'],
                    'number' =>  $tble['Order_table']['number'],
                    'reference_id' =>  $tble['Order_table']['reference_id'],
                    'is_alert' =>  $tble['Order_table']['is_alert'],
                    'is_waiter_required' =>  $tble['Order_table']['is_waiter_required'],
                    'status' =>  $tble['Order_table']['status'],
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'tables'=>$item
            );
        }
        return json_encode($response);
    }
    
    public function merge_table()
    {
        $cashierid       = $_REQUEST['id']                ?? '';
        $main_table_id   = $_REQUEST['main_table_ref_id'] ?? '';
        $merged_table_id = $_REQUEST['merge_table_ref_id'] ?? '';
    
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier Id Missing"]);
        }
        if (empty($main_table_id)) {
            return json_encode(['status' => false, 'message' => "Main Table Id Missing"]);
        }
        if (empty($merged_table_id)) {
            return json_encode(['status' => false, 'message' => "Merge Table Id Missing"]);
        }
        if($main_table_id==$merged_table_id){
            return json_encode(['status' => false, 'message' => "Main table and Merge Table Not Same"]);
        }
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'fields' => ['User.id'],
            'recursive' => -1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        $mainTable = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $main_table_id, 'Order_table.status' => 2],
            'fields' => ['Order_table.id', 'Order_table.reference_id', 'Order_table.number'],
            'recursive' => -1
        ]);
        if (empty($mainTable)) {
            return json_encode(['status' => false, 'message' => "Main Table Not found Or Not Booked...!"]);
        }
        
        $mergeTable = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $merged_table_id, 'Order_table.status IN' => [1,2]],
            'fields' => ['Order_table.id', 'Order_table.reference_id', 'Order_table.number'],
            'recursive' => -1
        ]);
        if (empty($mergeTable)) {
            return json_encode(['status' => false, 'message' => "Merge Table Not found...!"]);
        }
        
        $trackingData = [
            'main_table_id'      => $mainTable['Order_table']['id'],
            'main_table_number'  => $mainTable['Order_table']['number'],
            'main_table_ref_id'  => $mainTable['Order_table']['reference_id'],
            'merged_table_id'    => $mergeTable['Order_table']['id'],
            'merged_table_number'=> $mergeTable['Order_table']['number'],
            'merged_table_ref_id'=> $mergeTable['Order_table']['reference_id']
        ];
    
        if ($this->Order_table_tracking->save($trackingData)) {
            // $this->Order_table->updateAll(
            //     ['Order_table.status' => 4],
            //     ['Order_table.reference_id' => $merged_table_id]
            // );
            
            $this->Order_table->updateAll(
                array(
                    'Order_table.status' => 4,
                    'Order_table.sync' => 0,
                    'Order_table.local_sync' => 0
                ),
                array(
                    'Order_table.reference_id' => $merged_table_id
                )
            );
            
            return json_encode(['status' => true, 'message' => "Table Merged Successfully..!"]);
        }
    
        return json_encode(['status' => false, 'message' => "Table Merging not successful..!"]);
    }

    public function release_merge_table()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $merged_table_id = $_REQUEST['merge_table_ref_id'] ?? '';
    
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier Id Missing"]);
        }
        if (empty($merged_table_id)) {
            return json_encode(['status' => false, 'message' => "Merge Table Id Missing"]);
        }
    
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'fields' => ['User.id'], // optimize field selection
            'recursive' => -1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        $mergedTable = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $merged_table_id, 'Order_table.status' => 4],
            'fields' => ['Order_table.id'],
            'recursive' => -1
        ]);
        if (empty($mergedTable)) {
            return json_encode(['status' => false, 'message' => "Merge Tables Not found"]);
        }
    
        // $this->Order_table_tracking->updateAll(
        //     ['Order_table_tracking.status' => 0],
        //     ['Order_table_tracking.merged_table_ref_id' => $merged_table_id]
        // );
        $this->Order_table_tracking->updateAll(
            array(
                'Order_table_tracking.status' => 0,
                'Order_table_tracking.sync' => 0,
                'Order_table_tracking.local_sync' => 0
            ),
            array(
                'Order_table_tracking.merged_table_ref_id' => $merged_table_id
            )
        );

    
        // Generate unique reference_id
        do {
            $pin = 'TX' . $cashierid . date('Y') . uniqid();
        } while ($this->Order_table->hasAny(['Order_table.reference_id' => $pin]));
    
        // $this->Order_table->updateAll(
        //     ['Order_table.status' => 1, 'Order_table.reference_id' => "'$pin'"],
        //     ['Order_table.reference_id' => $merged_table_id]
        // );
        $this->Order_table->updateAll(
            array(
                'Order_table.status' => 1,
                'Order_table.reference_id' => "'" . $pin . "'",
                'Order_table.sync' => 0,
                'Order_table.local_sync' => 0
            ),
            array(
                'Order_table.reference_id' => $merged_table_id
            )
        );

    
        return json_encode(['status' => true, 'message' => "Table Released Successfully..!"]);
    }
    
    public function kds_discount()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id=$_REQUEST['reference_id'];
        $disc=$_REQUEST['discount'];
        $sc = $_REQUEST['service_charge'];
        $device_id = $_REQUEST['device_id'];
        $type = $_REQUEST['type'];
        $table = $_REQUEST['table'];
        $discount_type_value=$disc;
        $dish_type = $_REQUEST['kds'];
        
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($ref_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference id Missing",
            );
            return json_encode($response);
        }
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        
        
        if($sc==''){
            $response =array(
                'status'=> false,
                'message'=> "Service Charge Missing",
            );
            return json_encode($response);
        }
        
        if($device_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Device Id Missing",
            );
            return json_encode($response);
        }
        if($dish_type==''){
            $response =array(
                'status'=> false,
                'message'=> "Dish Type Missing",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        
        if($dish_type=='all'){
            $kdss = $this->Catalog_product->query("SELECT GROUP_CONCAT(kds) as kds FROM `catalog_product` WHERE id IN (SELECT product_id FROM `order_orderhistories` WHERE status!=0 and reference_id='$ref_id' group BY kds) and status=1");
            if(!empty($kdss))
            {
                foreach($kdss as $kdslist){
                    $kds=$kdslist[0]['kds'];
                }
            }
        }else{
            $kdss = $this->Catalog_product->query("SELECT GROUP_CONCAT(kds) as kds FROM `catalog_product` WHERE id IN (SELECT product_id FROM `order_orderhistories` WHERE status!=0 and reference_id='$ref_id' group BY kds) and status=1  and dish_type=$dish_type");
            if (!empty($kdss) && !empty($kdss[0][0]['kds']))
            {
                foreach($kdss as $kdslist){
                    $kds=$kdslist[0]['kds'];
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "No kds found for this dish type",
                );
                return json_encode($response);
            }
        }
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$disc,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
                if(empty($coup))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Coupon not found Or Coupon Expired",
                    );
                    return json_encode($response);
                }
                $disc=$coup['Coupon']['value'];
            }else{
                $disc=0;
            }
        }
        
        if($type==1){
            $disc=$disc;
        }
        
        if($type==2){
            if($dish_type=='all'){
                $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id='$ref_id'");
            }else{
                $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id='$ref_id' and kds IN ($kds)");
            }
            if($subtotals){
                $subtotal=$subtotals[0][0]['subtotal'];
                if($subtotal){
                    $disc=(($disc*100)/$subtotal);
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    );
                    return json_encode($response);
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Bill Not Found",
                );
                return json_encode($response);
            }
        }
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $kdsarray = explode(",", $kds);

        
        if($dish_type!='all'){
            $kdschk = $this->Pos_printer->find('first', array('conditions'=>array('Pos_printer.kds'=>$kdsarray,'Pos_printer.status'=>1)));
            if(empty($kdschk))
            {
                $response =array(
                    'status'=> false,
                    'message'=> "KDS not found",
                );
                return json_encode($response);
            }
        }
        if($dish_type!='all'){
            $kdschk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.kds'=>$kdsarray,'Order_orderhistory.status !='=>0)));
        }else{
            $kdschk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.status !='=>0)));
        }
        if(empty($kdschk))
        {
            $response =array(
                'status'=> false,
                'message'=> "No Item found for this KDS.",
            );
            return json_encode($response);
        }
        
        $packagechk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.package'=>1,'Order_orderhistory.status !='=>0)));
        if(!empty($packagechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "You can not Merge Discount with package.",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.cashier_id'=>$cashierid,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        
        if($table){
            $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.reference_id'=>$ref_id,'Order_table.status'=>3)));
            if(empty($tables)){
                $response['status']= false;
                $response['message']= "Table is not in billing state";
                return json_encode($response);
            }
        }
        
        $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id, 'Order_transaction.cashier_id'=>$cashierid)));
        if(empty($txnchk))
        {
            $response= array('status'=> false,
                'message'=> "No Transaction found"
            );
            return json_encode($response);
        }
        
        if($dish_type=='all'){
            $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        }else{
            $this->Order_tax->query("UPDATE order_tax SET discount_percentage='0',sync=0,local_sync=0 WHERE reference_id = '$ref_id'");
            $orderdata=$this->ordercomputewithkds($ref_id,$cashierid,$sc,$disc,$dish_type);
        }
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            $createtime = date('H:i:s');
            $this->Order_transaction->query("UPDATE `order_transactions` SET `price` = '$totalprice',`total_tax`='$totaltax',`servicecharge`='$totalservicechg',`discount`='$totaldiscount',`discount_type`='$type',`discount_type_value`='$discount_type_value',`amount`='$totalamount',`createtime`='$createtime',`name`='$name',`phone`='$phone',`address`='$address',sync=0,local_sync=0 WHERE `order_transactions`.`reference_id` = '$ref_id'");
            
            $response =array(
                'status'=> true,
                'message'=> "Saved",
            );
            return json_encode($response);
        }
        
        else{
            $response =array(
                'status'=> false,
                'message'=> "Not Saved",
            );
            return json_encode($response);
        }
    }
    public function ordercomputewithkds($txnid = null, $user_id = null, $is_sc = 1, $discount = 0, $dish = 0)
    {
        $response = ['status' => false];
    
        if (empty($txnid)) {
            return $response;
        }
    
        $sc = ($is_sc == 1) ? servicecharge : 0;
        $kds = (int)$dish; // dish type to filter discount
    
        // STEP 1: FETCH ALL ORDER ITEMS
        $items = $this->Order_orderhistory->find('all', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $txnid,
                'Order_orderhistory.status !=' => 0
            ],
            'fields' => [
                'Order_orderhistory.id',
                'Order_orderhistory.product_id',
                'Order_orderhistory.dish_type',
                'Order_orderhistory.price',
                'Order_orderhistory.quantity',
                'Order_orderhistory.discount',
                'Order_orderhistory.total_tax_percentage'
            ],
            'recursive' => -1
        ]);
    
        if (empty($items)) return $response;
    
        // STEP 2: CALCULATE TOTALS
        $totalprice = $totaldiscount = $totalservicechg = $totaltax = 0;
    
        foreach ($items as $row) {
            $item = $row['Order_orderhistory'];
    
            $basePrice = ($item['price'] * $item['quantity']) - $item['discount'];
            $applyDiscount = ($item['dish_type'] == $kds);
            $itemDiscount = $applyDiscount ? ($basePrice * $discount) / 100 : 0;
    
            $priceAfterDiscount = $basePrice - $itemDiscount;
            $serviceCharge = ($priceAfterDiscount * $sc) / 100;
            $taxableAmount = $priceAfterDiscount + $serviceCharge;
            $taxValue = ($taxableAmount * $item['total_tax_percentage']) / 100;
    
            $totalprice += $basePrice;
            $totaldiscount += $itemDiscount;
            $totalservicechg += $serviceCharge;
            $totaltax += $taxValue;
        }

        // STEP 3: UPDATE ORDER TAX (RESET + APPLY)
        $taxRows = $this->Order_tax->find('all', [
            'conditions' => [
                'Order_tax.reference_id' => $txnid,
                'Order_tax.status !=' => 0
            ],
            'fields' => [
                'Order_tax.id',
                'Order_tax.orderhistory_id',
                'Order_tax.tax_percentage',
                'Order_tax.quantity'
            ],
            'recursive' => -1
        ]);
    
        // Build a lookup map
        $itemMap = [];
        foreach ($items as $itemRow) {
            $itemMap[$itemRow['Order_orderhistory']['id']] = $itemRow['Order_orderhistory'];
        }
    
        foreach ($taxRows as $row) {
            $tax = $row['Order_tax'];
    
            if (!isset($itemMap[$tax['orderhistory_id']])) continue;
    
            $item = $itemMap[$tax['orderhistory_id']];
    
            $basePrice = ($item['price'] * $tax['quantity']) - $item['discount'];
    
            // Use the item’s dish_type to determine discount
            $applyDiscount = ($item['dish_type'] == $kds);
            $itemDiscount = $applyDiscount ? ($basePrice * $discount) / 100 : 0;
    
            $priceAfterDiscount = $basePrice - $itemDiscount;
            $serviceCharge = ($priceAfterDiscount * $sc) / 100;
            $taxablePrice = round($priceAfterDiscount + $serviceCharge, 2);
            $taxValue = round(($taxablePrice * $tax['tax_percentage']) / 100, 2);
            $discountPercent = $applyDiscount ? (float)$discount : 0.0;
    
            // Update tax row
            try {
                $this->Order_tax->updateAll(
                    [
                        'taxable_price' => (float)$taxablePrice,
                        'tax_value' => (float)$taxValue,
                        'discount_percentage' => $discountPercent,
                        'dish_type' => (int)$item['dish_type'], // crucial: copy dish_type from item
                        'sync' => 0,
                        'local_sync' => 0
                    ],
                    ['id' => (int)$tax['id']]
                );
                
                $db = $this->Order_tax->getDataSource();
                if ($db->lastError()) {
                    $this->trackUser($txnid,$user_id,'order_tax_sql_error1',[
                        'tax_id'=>$tax['id'],
                        'error'=>$db->lastError()
                    ]);
                }
            } catch (Exception $e) {
                $this->trackUser($txnid, $user_id, 'order_tax_update_error', [
                    'tax_id' => $tax['id'],
                    'error' => $e->getMessage()
                ]);
            }
        }
    
        // STEP 4: RETURN TOTALS
        return [
            'status' => true,
            'totalprice' => round($totalprice, 2),
            'totaldiscount' => round($totaldiscount, 2),
            'totalservicechg' => round($totalservicechg, 2),
            'totaltax' => round($totaltax, 2)
        ];
    }


    public function save_customer_details()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $ref_id = $_REQUEST['ref_id'] ?? '';
        $name = $_REQUEST['name'] ?? '';
        $phone = $_REQUEST['phone'] ?? '';
        $address = $_REQUEST['address'] ?? '';
        $pax = $_REQUEST['pax'] ?? '';
    
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier Id Missing"]);
        }
        if (empty($ref_id)) {
            return json_encode(['status' => false, 'message' => "Table Ref Id Missing"]);
        }
        if (empty($pax)) {
            return json_encode(['status' => false, 'message' => "PAX Missing"]);
        }
    
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'fields' => ['User.id'], // optimize field selection
            'recursive' => -1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        $tablechk = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $ref_id],
            'fields' => ['Order_table.id','Order_table.pax'],
            'recursive' => -1
        ]);
        if (empty($tablechk)) {
            return json_encode(['status' => false, 'message' => "Table Not found"]);
        }
        $table_pax = $tablechk['Order_table']['pax'];
        
        if($pax>$table_pax){
            return json_encode(['status' => false, 'message' => "PAX is not more then table limit."]);
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.customer_name' => "'" . addslashes($name) . "'",
                'Order_table.customer_phone' => "'" . addslashes($phone) . "'",
                'Order_table.customer_address' => "'" . addslashes($address) . "'",
                'Order_table.customer_pax' => "'" . addslashes($pax) . "'",
                'Order_table.sync'             => 0,
                'Order_table.local_sync'       => 0
            ],
            ['Order_table.reference_id' => $ref_id]
        );

    
        return json_encode(['status' => true, 'message' => "Customer Details updated Successfully..!"]);
    }
    
    public function get_customer_details()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $ref_id = $_REQUEST['ref_id'] ?? '';
    
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier ID missing"]);
        }
    
        if (empty($ref_id)) {
            return json_encode(['status' => false, 'message' => "Table reference ID missing"]);
        }
    
        // Check if user exists
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'fields' => ['User.id'],
            'recursive' => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        // Get table details
        $tablechk = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $ref_id],
            'fields' => ['Order_table.id', 'Order_table.customer_name', 'Order_table.customer_phone', 'Order_table.customer_address', 'Order_table.customer_pax', 'Order_table.status'],
            'recursive' => -1
        ]);
    
        if (empty($tablechk)) {
            return json_encode(['status' => false, 'message' => "Table not found"]);
        }
        
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        if($tablechk['Order_table']['status']==1){
            $customer_pax = '';
        }else{
            $customer_pax = trim($tablechk['Order_table']['customer_pax']);
        }
    
        return json_encode([
            'status' => true,
            'message' => "Customer Found.",
            'name' => $name,
            'phone' => $phone,
            'address' => $address,
            'pax' => $customer_pax
        ]);
    }

    public function get_customer_details_by_phone()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $phone = $_REQUEST['phone'] ?? '';
    
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier ID missing"]);
        }
    
        if (empty($phone)) {
            return json_encode(['status' => false, 'message' => "Phone number missing"]);
        }
    
        // Validate user
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'fields' => ['User.id'],
            'recursive' => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        // Get customer details by phone
        $customer = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone, 'status' => 1],
            'fields' => ['Order_customers.name', 'Order_customers.phone', 'Order_customers.address'],
            'recursive' => -1
        ]);
    
        if (empty($customer)) {
            return json_encode(['status' => false, 'message' => "Customer not found"]);
        }
    
        $name    = trim($customer['Order_customers']['name']);
        $address = trim($customer['Order_customers']['address']);
    
        return json_encode([
            'status' => true,
            'message' => "Customer details found.",
            'name'    => $name,
            'phone'   => $phone,
            'address' => $address
        ]);
    }
    
    //takeaway APIS
    public function create_takeaway_table()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $name = $_REQUEST['name'] ?? '';
        $phone = $_REQUEST['phone'] ?? '';
        $address = $_REQUEST['address'] ?? '';
        
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "Cashier Id Missing"]);
        }
        if (empty($name)) {
            return json_encode(['status' => false, 'message' => "Customer Name Missing"]);
        }
        if (empty($phone)) {
            return json_encode(['status' => false, 'message' => "Customer Phone Missing"]);
        }
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive' => -1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
        
        $tablechk = $this->Order_table->find('first', [
            'conditions' => ['Order_table.number' => $phone],
            'fields' => ['Order_table.id'],
            'recursive' => -1
        ]);
        if (!empty($tablechk)) {
            return json_encode(['status' => false, 'message' => "Table Already Exist"]);
        }
        
        do {
            $txnid = '';
            for ($i = 0; $i < 10; $i++) {
                $txnid .= rand(1, 9);
            }
            $existingOTP = $this->Order_transaction->find('first', array(
                'conditions' => array(
                    'reference_id' => $txnid
                )
            ));
        } while ($existingOTP); // Continue generating OTP until it doesn't exist
        
        $data['Order_table']=array(
            'number'=>$phone,
            'reference_id'=>$txnid,
            'cover_charge'=>0,
            'weekend_charge'=>0,
            'pax'=>0,
            'customer_name'=>$name,
            'customer_phone'=>$phone,
            'customer_address'=>$address,
            'location_id'=>$user['User']['location_id'],
            'location_name'=>$user['User']['location_name'],
            'is_takeaway'=>1
        );
      
        if($this->Order_table->saveAll($data['Order_table']))
        {
            $last_id = $this->Order_table->id; // ✅ last inserted ID
            
            return json_encode(['id' => $phone,'number' => $phone,'reference_id' => $txnid,'is_takeaway' => '1','status' => true, 'message' => "Customer Details updated Successfully..!"]);
        }else{
            return json_encode(['status' => false, 'message' => "Customer Details Not updated Successfully..!"]);
        }
        
    }
    
    public function takeaway_table_list()
    {
        $cashierid = $_REQUEST['id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        if(isset($_REQUEST['status'])){
            $tbles = $this->Order_table->find('all', array('conditions'=>array('status'=>$_REQUEST['status'],'is_takeaway'=>1)));
        }else{
            $tbles = $this->Order_table->find('all', array('conditions'=>array('status !='=>0,'is_takeaway'=>1)));
        }
        if(empty($tbles))
        {
            $response =array(
                'status'=> false,
                'message'=> "Tables Not found ",
            );
            return json_encode($response);
        }else{
            foreach($tbles as $tble){
                $sc=0;
                $disc=0;
                $tablereference_id=$tble['Order_table']['reference_id'];
                $orderdata=$this->ordercomputewithdiscount($tablereference_id,$cashierid,$sc,$disc);
                $amount=$orderdata['totalprice'];
                
                $item[]=array(
                    'id' => $tble['Order_table']['number'],
                    'number' =>  $tble['Order_table']['number'],
                    'reference_id' =>  $tble['Order_table']['reference_id'],
                    'amount' =>  isset($amount) ? (string)$amount : "0",
                    'is_alert' =>  $tble['Order_table']['is_alert'],
                    'is_waiter_required' =>  $tble['Order_table']['is_waiter_required'],
                    'is_customer_detail_required' =>  $tble['Order_table']['is_customer_detail_required']?$tble['Order_table']['is_customer_detail_required']:"0",
                    'status' =>  $tble['Order_table']['status'],
                    'is_takeaway' =>  $tble['Order_table']['is_takeaway']
                );
            }
            $response= array('status'=> true,
                'message'=> "success",
                'tables'=>$item
            );
        }
        return json_encode($response);
    }
    
    //kds 
    public function kds_login()
    {
        $username = $_REQUEST['username'] ?? '';
        $password = $_REQUEST['password'] ?? '';
        
        if (empty($username)) {
            return json_encode(['status' => false, 'message' => "Username missing..!"]);
        }
        
        if (empty($password)) {
            return json_encode(['status' => false, 'message' => "Password missing..!"]);
        }
        
        $password = AuthComponent::password($password);
        
        $user = $this->Kds_user->find('first', [
            'conditions' => [
                'Kds_user.username' => $username,
                'Kds_user.password' => $password,
                'Kds_user.status' => 1
            ],
            'recursive' => 1
        ]);
        
        $stations = [];
        if (!empty($user)) {
            // $kds_stations = $this->Kds_users_station_mapping->find('all', [
            //     'conditions' => [
            //         'Kds_users_station_mapping.kds_id' => $user['Kds_user']['id'],
            //         'Kds_users_station_mapping.status' => 1
            //     ],
            //     'recursive' => 1
            // ]);
        
            // foreach ($kds_stations as $kds_station) {
            //     $stations[] = [
            //         'station_id' => $kds_station['Kds_users_station_mapping']['station_id'] ?? '',
            //         'station_name' => $kds_station['Kds_users_station_mapping']['station_name'] ?? '',
            //         'station_store_id' => $kds_station['Kds_users_station_mapping']['station_store_id'] ?? '',
            //         'station_store_name' => $kds_station['Kds_users_station_mapping']['station_store_name'] ?? '',
            //         'station_created' => $kds_station['Kds_users_station_mapping']['created'] ?? ''
            //     ];
            // }
        
            $response = [
                'status' => true,
                'message' => "Success..!",
                'id' => $user['Kds_user']['id'] ?? '',
                'username' => $user['Kds_user']['username'] ?? '',
                'role' => $user['Kds_user']['role'] ?? '',
                'location_id' => $user['Kds_user']['location_id'] ?? '',
                'location_name' => $user['Kds_user']['location_name'] ?? '',
                'user_status' => $user['Kds_user']['status'] ?? '',
                'created' => $user['Kds_user']['created'] ?? '',
                // 'stations' => $stations
            ];
        } else {
            $response = ['status' => false, 'message' => "Failed..!"];
        }
        
        return json_encode($response);
    }
    
    public function kds_listing()
    {
        $this->autoRender = false;
        $kds = $_REQUEST['station_id'] ?? '';
    
        if (empty($kds)) {
            return json_encode(['status' => false, 'message' => "KDS Id Missing"]);
        }
        
        $date = date("Y-m-d");
        if (empty($date)) {
            return json_encode(['status' => false, 'message' => "Date Missing"]);
        }
    
        $result = $this->Order_orderhistory->query("
            SELECT *,
                (SELECT waiter_name FROM order_tables WHERE reference_id = order_orderhistories.reference_id) AS waiter_name
            FROM order_orderhistories
            WHERE DATE(created) = '$date'
                AND status != 0
                
            GROUP BY reference_id, group_id
        ");
        if (empty($result)) {
            return json_encode(['status' => false, 'message' => "No Order found"]);
        }
    
        $orders = [];
    
        foreach ($result as $order) {
            $reference_id = $order['order_orderhistories']['reference_id'];
            $group_id = $order['order_orderhistories']['group_id'];
    
            $orderitems = $this->Order_orderhistory->query("
                SELECT * FROM order_orderhistories
                WHERE DATE(created) = '$date'
                    AND status != 0
                    AND reference_id = '$reference_id'
                    AND group_id = '$group_id'
            ");
        
            $items = [];
            foreach ($orderitems as $orderitem) {
                $reference_id=$orderitem['order_orderhistories']['reference_id'];
                $product_id=$orderitem['order_orderhistories']['product_id'];
                $order_id=$orderitem['order_orderhistories']['id'];
                
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                $items[] = array(
                    'order_history_id' => $orderitem['order_orderhistories']['id'],
                    'item_id'       => $orderitem['order_orderhistories']['product_id'],
                    'quantity'         => $orderitem['order_orderhistories']['quantity'],
                    'item_name'     => $orderitem['order_orderhistories']['product_name'],
                    'modifiers' => $selected_modifiers
                );
            }
    
            $orders[] = array(
                'kds_ref_id'   => $reference_id,
                'kds_group_id' => $group_id,
                'table_no'     => $order['order_orderhistories']['table_number'],
                'created'      => $order['order_orderhistories']['created'],
                'waiter_name'  => $order['order_orderhistories']['waiter_name'] ?? '',
                'kds_status'   => $order['order_orderhistories']['kds_status'],
                'items'        => $items
            );
        }
    
        return json_encode(['status' => true, 'orders' => $orders]);
    }
    
    public function kds_status_update()
    {
        $this->autoRender = false;
    
        $kds_user_id = $_REQUEST['kds_user_id'] ?? '';
        $reference_id = $_REQUEST['reference_id'] ?? '';
        $order_id = $_REQUEST['order_history_id'] ?? '';
        $status = $_REQUEST['status'] ?? '';
    
        if (empty($kds_user_id)) {
            return json_encode(['status' => false, 'message' => "KDS User Id Missing"]);
        }
        if (empty($reference_id)) {
            return json_encode(['status' => false, 'message' => "Reference Id Missing"]);
        }
        if (empty($order_id)) {
            return json_encode(['status' => false, 'message' => "Order ID Missing"]);
        }
        if (empty($status)) {
            return json_encode(['status' => false, 'message' => "Status Missing"]);
        }
    
        $user = $this->Kds_user->find('first', [
            'conditions' => [
                'Kds_user.id' => $kds_user_id,
                'Kds_user.status' => 1
            ],
            'recursive' => 1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => "KDS user not found"]);
        }
    
        $orders = $this->Order_orderhistory->find('first', [
            'conditions' => [
                'id' => $order_id,
                'reference_id' => $reference_id,
                'status !=' => 0
            ]
        ]);
        if (empty($orders)) {
            return json_encode(['status' => false, 'message' => "Order not found"]);
        }
    
        $data['Kds_track'][] = [
            'order_history_id'   => $order_id,
            'order_reference_id' => $reference_id,
            'kds_group_id'       => $orders['Order_orderhistory']['group_id'],
            'kds_user_id'        => $kds_user_id,
            'product_id'         => $orders['Order_orderhistory']['product_id'],
            'product_name'       => $orders['Order_orderhistory']['product_name'],
            'status'             => $status
        ];
    
        $track_id = null;
        if (empty($data['Kds_track'])) {
            return json_encode(['status' => false, 'message' => "data not found"]);
        }
        
        $this->Kds_track->create();
        $this->Kds_track->saveAll($data['Kds_track']);
        $track_id = $this->Kds_track->id; // ✅ last inserted id
        
        // Update Order_orderhistory
        $this->Order_orderhistory->updateAll(
            [
                'Order_orderhistory.kds_track_id' => "'$track_id'",
                'Order_orderhistory.kds_status'   => "'$status'",
                'Order_orderhistory.sync'         => 0,
                'Order_orderhistory.local_sync'   => 0
            ],
            ['Order_orderhistory.id' => $order_id]
        );
    
        return json_encode(['status' => true, 'message' => "KDS Status Updated", 'track_id' => $track_id]);
    }

    
    public function online_order_accept()
    {
        $cashierid    = isset($_REQUEST['id'])           ? $_REQUEST['id']           : '';
        $reference_id = isset($_REQUEST['reference_id']) ? $_REQUEST['reference_id'] : '';

        if ($cashierid == '') {
            return json_encode(array('status' => false, 'message' => "User Id Missing"));
        }

        $users = $this->User->find('first', array('conditions' => array('User.id' => $cashierid, 'User.status' => 1)));
        if (empty($users)) {
            return json_encode(array('status' => false, 'message' => "Cashier not found"));
        }

        if ($reference_id == '') {
            return json_encode(array('status' => false, 'message' => "Reference Id Missing"));
        }

        // Idempotency: if POS records already created, return success
        $already = $this->Order_transaction->find('first', array(
            'conditions' => array('Order_transaction.reference_id' => $reference_id)
        ));
        if (!empty($already)) {
            return json_encode(array('status' => false, 'message' => "Order already accepted"));
        }

        // Load the pending online_order row
        $webhook = $this->Online_order->find('first', array(
            'conditions' => array(
                'Online_order.reference_id' => $reference_id,
                'Online_order.status'       => 0
            )
        ));

        if (empty($webhook)) {
            return json_encode(array('status' => false, 'message' => "Order not found or already processed"));
        }

        $txnid    = $webhook['Online_order']['reference_id'];
        $upOrderId = $webhook['Online_order']['order_id'];
        $storeId   = $webhook['Online_order']['store_id'];

        // Parse canonical payload saved by LocalUpController::order_create()
        $payload    = json_decode($webhook['Online_order']['response'], true);
        $header     = isset($payload['header'])     ? $payload['header']     : array();
        $financials = isset($payload['financials']) ? $payload['financials'] : array();
        $items      = isset($payload['items'])      ? $payload['items']      : array();

        if (empty($items)) {
            return json_encode(array('status' => false, 'message' => "Order has no items"));
        }

        $storeId       = isset($header['store_id'])          ? $header['store_id']         : $storeId;
        $displayId     = isset($header['up_display_id'])     ? $header['up_display_id']     : $upOrderId;
        $paymentMode   = isset($header['payment_mode'])      ? $header['payment_mode']      : 'prepaid';
        $channel       = isset($header['channel'])           ? $header['channel']           : 'online';
        $instructions  = isset($header['instructions'])      ? $header['instructions']      : '';
        $isTakeaway    = !empty($header['is_takeaway'])       ? 1                            : 0;
        $customer      = isset($header['customer'])          ? $header['customer']          : array();
        $custName      = isset($customer['name'])  ? $customer['name']  : 'Online Customer';
        $custPhone     = isset($customer['phone']) ? $customer['phone'] : '';
        $custAddress   = isset($customer['email']) ? $customer['email'] : '';

        $subtotal        = (float)(isset($financials['subtotal'])          ? $financials['subtotal']          : 0);
        $totalTax        = (float)(isset($financials['total_taxes'])       ? $financials['total_taxes']       : 0);
        $deliveryCharge  = (float)(isset($financials['delivery_charges'])  ? $financials['delivery_charges']  : 0);
        $packagingCharge = (float)(isset($financials['packaging_charges']) ? $financials['packaging_charges'] : 0);
        $serviceCharge   = (float)(isset($financials['service_charges'])   ? $financials['service_charges']   : 0);
        $discount        = (float)(isset($financials['discount'])          ? $financials['discount']          : 0);
        $payableAmount   = (float)(isset($financials['payable_amount'])    ? $financials['payable_amount']    : 0);
		
		
        $otherTaxes = 0;
        $otherTaxes = (float)(isset($payload['other_charges']) ? $payload['other_charges'] : 0);

        // Totals accumulated from items
        $totalItemsPrice  = 0;
        $totalTaxCalc     = 0;
        $groupId          = rand(0,9) . $cashierid . time();
        $deviceId         = 'UP_CONNECTOR';
        
        $kotDate = date('Y-m-d'); // ensure correct format
        $tdaykot = $this->Order_orderhistory->query("
            SELECT kot_number 
            FROM order_orderhistories 
            WHERE store_id = '$storeId' 
            ORDER BY id DESC 
            LIMIT 1
        ");

        $kot_no=1;
        if (!empty($tdaykot) && isset($tdaykot[0]['order_orderhistories']['kot_number'])) {
            $kot_no = $tdaykot[0]['order_orderhistories']['kot_number'] + 1;
        }

        foreach ($items as $item) {
            $qty       = (int)(isset($item['qty'])        ? $item['qty']        : 1);
            $unitPrice = (float)(isset($item['unit_price'])  ? $item['unit_price']  : 0);
            $itemDisc  = (float)(isset($item['discount'])    ? $item['discount']    : 0);
            $itemTotal = (float)(isset($item['total_price']) ? $item['total_price'] : $unitPrice * $qty);
            $catId     = isset($item['category_id'])   ? $item['category_id']   : 0;
            $catName   = isset($item['category_name']) ? $item['category_name'] : '';

            // Sum item-level taxes from canonical payload
            $itemTax    = 0;
            $itemTaxPct = 0;
            if (!empty($item['taxes']) && is_array($item['taxes'])) {
                foreach ($item['taxes'] as $t) {
                    $itemTax    += (float)(isset($t['value']) ? $t['value'] : 0);
                    $itemTaxPct += (float)(isset($t['rate'])  ? $t['rate']  : 0);
                }
            }
            $totalTaxCalc    += $itemTax;
            $totalItemsPrice += $itemTotal;

            $kdsDetails = $this->Catalog_product->find('first', array(
                'fields' => array('Catalog_product.kds'),
                'conditions' => array(
                    'Catalog_product.id' => $item['merchant_id'],
                    'Catalog_product.status' => 1
                )
            ));

            $kdsid = $kdsDetails['Catalog_product']['kds'];

            // Save order_orderhistory row
            $ohData = array(
                'reference_id'         => $txnid,
                'group_id'             => $groupId,
                'cashier_id'           => $cashierid,
                'store_id'             => $storeId,
                'category'             => $catId,
                'category_name'        => $catName,
                'kds'                  => $kdsid,
                'product_id'           => isset($item['merchant_id']) ? $item['merchant_id'] : 0,
                'product_name'         => isset($item['name']) ? $item['name'] : '',
                'quantity'             => $qty,
                'price'                => $unitPrice,
                'total_price'          => $itemTotal,
                'total_tax'            => round($itemTax, 2),
                'total_tax_percentage' => round($itemTaxPct, 2),
                'discount'             => $itemDisc,
                'device_id'            => $deviceId,
                'kds_status'           => 3,
                'kot_number'           =>$kot_no,
                'kot_date'             =>$kotDate,
                'remarks'              => $instructions,
                'status'               => 2,
                'sync'                 => 0,
                'local_sync'           => 0,
            );
            $this->Order_orderhistory->create();
            $this->Order_orderhistory->save(array('Order_orderhistory' => $ohData));
            $lastOhId = $this->Order_orderhistory->getLastInsertID();

            // Save order_modifier rows for item options (addons)
            if (!empty($item['options']) && is_array($item['options'])) {
                foreach ($item['options'] as $opt) {
                    $modData = array(
                        'orderhistory_id'     => $lastOhId,
                        'product_id'          => isset($item['merchant_id']) ? $item['merchant_id'] : 0,
                        'product_name'        => isset($item['name']) ? $item['name'] : '',
                        'modifier_group_id'   => isset($opt['group_id'])    ? (int)$opt['group_id']    : 0,
                        'modifier_group_name' => isset($opt['group_title']) ? $opt['group_title']      : '',
                        'modifier_group_type' => 0,
                        'modifier_id'         => isset($opt['option_id'])   ? (int)$opt['option_id']   : 0,
                        'modifier_name'       => isset($opt['option_name']) ? $opt['option_name']      : '',
                        'modifier_price'      => (float)(isset($opt['price']) ? $opt['price'] : 0),
                        'quantity'            => (int)(isset($opt['qty']) ? $opt['qty'] : 1),
                        'reference_id'        => $txnid,
                        'store_id'            => $storeId,
                        'status'              => 1,
                        'sync'                => 0,
                        'local_sync'          => 0,
                    );
                    $this->Order_modifier->create();
                    $this->Order_modifier->save(array('Order_modifier' => $modData));
                }
            }

            // Save order_tax rows with UP→local tax mapping
            if (!empty($item['taxes']) && is_array($item['taxes'])) {
                $discPct = ($unitPrice > 0) ? round(($itemDisc * 100) / ($unitPrice * $qty), 2) : 0;
                foreach ($item['taxes'] as $t) {
                    $tName  = isset($t['title']) ? $t['title'] : (isset($t['name']) ? $t['name'] : 'Tax');
                    $tRate  = (float)(isset($t['rate'])  ? $t['rate']  : 0);
                    $tValue = (float)(isset($t['value']) ? $t['value'] : 0);

                    $mappedTax = $this->_resolveUpTax($tName, $tRate, $storeId);

                    $taxData = array(
                        'orderhistory_id'      => $lastOhId,
                        'store_id'             => $storeId,
                        'product_id'           => isset($item['merchant_id']) ? $item['merchant_id'] : 0,
                        'product_name'         => isset($item['name']) ? $item['name'] : '',
                        'price'                => $unitPrice,
                        'taxable_price'        => round($itemTotal, 2),
                        'cat_id'               => $catId,
                        'cat_name'             => $catName,
                        'discount_percentage'  => $discPct,
                        'quantity'             => $qty,
                        'tax_id'               => $mappedTax['tax_id'],
                        'tax_name'             => $mappedTax['tax_name'],
                        'tax_percentage'       => $mappedTax['tax_percentage'],
                        'tax_value'            => round($tValue, 2),
                        'reference_id'         => $txnid,
                        'status'               => 2,
                        'sync'                 => 0,
                        'local_sync'           => 0,
                    );
                    $this->Order_tax->create();
                    $this->Order_tax->save(array('Order_tax' => $taxData));
                }
            }
        }

        // Save order_customers (upsert by phone)
        if (!empty($custPhone)) {
            $ds = $this->Order_transaction->getDataSource();
            $ds->query(
                'INSERT INTO order_customers (phone, name, status, sync, local_sync) VALUES (' .
                $ds->value($custPhone) . ',' .
                $ds->value($custName)  . ', 1, 0, 0) ' .
                'ON DUPLICATE KEY UPDATE name = VALUES(name)'
            );
        }

        // Calculate token and round
        $todayDate   = date('Y-m-d');
        $currentTime = date('H:i:s');
        $tdaytrx = $this->Order_transaction->query(
            "SELECT COUNT(id) as tkn FROM order_transactions WHERE date(created)='$todayDate' AND status=2"
        );
        $token = (isset($tdaytrx[0][0]['tkn']) ? (int)$tdaytrx[0][0]['tkn'] : 0) + 1;

        $gross      = $payableAmount ?: ($totalItemsPrice + ($totalTax ?: $totalTaxCalc) + $deliveryCharge + $packagingCharge + $serviceCharge - $discount);
        $grossRound = round($gross);
        $roundDiff  = round($grossRound - $gross, 2);

        // Save order_transaction
        // $payType   = ($paymentMode === 'prepaid') ? 6 : 1;
        $payType = 11;
        $txnData = array(
            'reference_id'       => $txnid,
            'group_id'           => $groupId,
            'device_id'          => $deviceId,
            'cashier_id'         => $cashierid,
            'store_id'           => $storeId,
            'orderno'            => $displayId,
            'name'               => $custName,
            'phone'              => $custPhone,
            'address'            => $custAddress,
            'price'              => $subtotal ?: $totalItemsPrice,
            'total_tax'          => $totalTax ?: round($totalTaxCalc, 3),
            'other_taxes'        => round($otherTaxes, 2),
            'servicecharge'      => $serviceCharge,
            'delivery_charge'    => $deliveryCharge,
            'packing_charge'     => $packagingCharge,
            'discount'           => $discount,
            'discount_type'      => 2,
            'discount_type_value'=> $discount,
            'amount'             => $grossRound,
            'round'              => $roundDiff,
            'is_takeaway'        => $isTakeaway,
            'payment_mode'       => ($paymentMode === 'prepaid') ? 'Online' : 'Cash',
            'tokenno'            => $token,
            'createtime'         => $currentTime,
            'remarks'            => $instructions,
            'status'             => 2,
            'sync'               => 0,
            'local_sync'         => 0,
        );
        $this->Order_transaction->create();
        $this->Order_transaction->save(array('Order_transaction' => $txnData));

        // Save order_payment
        $payData = array(
            'reference_id' => $txnid,
            'store_id'     => $storeId,
            'device_id'    => $deviceId,
            'cashier_id'   => $cashierid,
            'type'         => $payType,
            'type_value'   => $channel,
            'amount'       => $grossRound,
            'round'        => $roundDiff,
            'status'       => 2,
            'sync'         => 0,
            'local_sync'   => 0,
        );
        $this->Order_payment->create();
        $this->Order_payment->save(array('Order_payment' => $payData));

        // Update online_order status to accepted (1)
        $this->Online_order->updateAll(
            array(
                'Online_order.status'     => 1,
                'Online_order.cron_run'   => 1,
                'Online_order.sync'       => 0,
                'Online_order.local_sync' => 0,
            ),
            array('Online_order.reference_id' => $txnid)
        );

        // Acknowledge to UrbanPiper
        if (!empty($upOrderId)) {
            App::uses('UrbanpiperClient', 'Lib/Urbanpiper');
            App::uses('UrbanpiperLogger', 'Lib/Urbanpiper');
            try {
                $upClient = new UrbanpiperClient();
                $ackResult = $upClient->acknowledgeOrder($upOrderId);
                if (!$ackResult['success']) {
                    UrbanpiperLogger::warn('online_order_accept ack FAILED up_order_id=' . $upOrderId . ' http=' . $ackResult['http_code']);
                }
            } catch (Exception $e) {
                // Non-fatal — order is accepted locally
            }
        }

        return json_encode(array('status' => true, 'message' => "Order accepted"));
    }
    
    private function _resolveUpTax($taxName, $taxRate, $storeId) {
        $ds = $this->Order_transaction->getDataSource();

        // 1. Try store-specific mapping
        $rows = $ds->query(
            'SELECT local_tax_id, local_tax_name, local_tax_percentage FROM up_tax_map' .
            ' WHERE up_tax_name = ' . $ds->value($taxName) .
            ' AND up_tax_rate = '   . $ds->value($taxRate) .
            ' AND store_id = '      . $ds->value($storeId) .
            ' AND status = 1 LIMIT 1'
        );

        if (empty($rows)) {
            // 2. Try global mapping (store_id IS NULL)
            $rows = $ds->query(
                'SELECT local_tax_id, local_tax_name, local_tax_percentage FROM up_tax_map' .
                ' WHERE up_tax_name = ' . $ds->value($taxName) .
                ' AND up_tax_rate = '   . $ds->value($taxRate) .
                ' AND store_id IS NULL' .
                ' AND status = 1 LIMIT 1'
            );
        }

        if (!empty($rows)) {
            $r = isset($rows[0]['up_tax_map']) ? $rows[0]['up_tax_map'] : $rows[0][0];
            return array(
                'tax_id'         => (int)$r['local_tax_id'],
                'tax_name'       => $r['local_tax_name'] ?: $taxName,
                'tax_percentage' => (float)$r['local_tax_percentage'],
            );
        }

        // 3. Not mapped: look up catalog_tax by name/percentage
        $catRows = $ds->query(
            'SELECT id, name, percentage FROM catalog_tax' .
            ' WHERE name LIKE ' . $ds->value('%' . $taxName . '%') .
            ' AND status = 1 LIMIT 1'
        );

        $localTaxId  = 0;
        $localTaxPct = $taxRate;
        $localTaxName = $taxName;

        if (!empty($catRows)) {
            $cr = isset($catRows[0]['catalog_tax']) ? $catRows[0]['catalog_tax'] : $catRows[0][0];
            $localTaxId   = (int)$cr['id'];
            $localTaxPct  = (float)$cr['percentage'];
            $localTaxName = $cr['name'];
        } else {
            // Create a new catalog_tax entry so it shows in reports
            $ds->query(
                'INSERT IGNORE INTO catalog_tax (name, percentage, status) VALUES (' .
                $ds->value($taxName) . ',' .
                $ds->value($taxRate) . ', 1)'
            );
            $catNew = $ds->query(
                'SELECT id FROM catalog_tax WHERE name = ' . $ds->value($taxName) . ' LIMIT 1'
            );
            if (!empty($catNew)) {
                $cr = isset($catNew[0]['catalog_tax']) ? $catNew[0]['catalog_tax'] : $catNew[0][0];
                $localTaxId = (int)$cr['id'];
            }
        }

        // Auto-register global mapping for future orders
        if ($localTaxId > 0) {
            $ds->query(
                'INSERT IGNORE INTO up_tax_map' .
                ' (up_tax_name, up_tax_rate, local_tax_id, local_tax_name, local_tax_percentage)' .
                ' VALUES (' .
                $ds->value($taxName) . ',' .
                $ds->value($taxRate) . ',' .
                $ds->value($localTaxId) . ',' .
                $ds->value($localTaxName) . ',' .
                $ds->value($localTaxPct) . ')'
            );
        }

        return array(
            'tax_id'         => $localTaxId,
            'tax_name'       => $localTaxName,
            'tax_percentage' => $localTaxPct,
        );
    }
    
     public function online_order_transaction_history()
    {
        // fetch according to store id 
        $cashierid = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
    
        $startdate = isset($_REQUEST['from']) ? $_REQUEST['from'] : date("Y-m-d");
        $enddate   = isset($_REQUEST['to'])   ? $_REQUEST['to']   : date("Y-m-d");
        
        // Build shift datetime range
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        if ($cashierid == '') {
            return json_encode([
                'status'  => false,
                'message' => "User Id Missing",
            ], JSON_UNESCAPED_UNICODE);
        }
    
        $users = $this->User->find('first', [
            'conditions' => [
                'User.id'     => $cashierid,
                'User.status' => 1
            ]
        ]);
    
        if (empty($users)) {
            return json_encode([
                'status'  => false,
                'message' => "Cashier not found",
            ], JSON_UNESCAPED_UNICODE);
        }
    
        $store_id = $users['User']['location_id'];
        $transactionitems = [];
    
        $transactions = $this->Online_order->find('all', [
            'conditions' => [
                'store_id' => $store_id,
                'created BETWEEN ? AND ?' => [
                    $startDatetime,
                    $endDatetime
                ],
                'status NOT IN' => [2, 5]
            ],
            'order' => ['Online_order.id' => 'DESC']
        ]);
    
        if (!empty($transactions)) {
            foreach ($transactions as $orders) {
                $total_pack_charge = 0;
    
                $finalamount   = $orders['Online_order']['total_amount'];
                $cashier_id    = $orders['Online_order']['cashier_id'];
                $reference_id  = $orders['Online_order']['reference_id'];
                $response      = $orders['Online_order']['response'];
                $response_res  = json_decode($response, true);
    
                if (json_last_error() !== JSON_ERROR_NONE) {
                    // skip invalid json responses
                    continue;
                }
    
                // packaging charges — canonical stores this as a flat number in financials
                if (isset($response_res['financials']['packaging_charges'])) {
                    $total_pack_charge = (float)$response_res['financials']['packaging_charges'];
                }
    
                // timestamps — canonical stores delivery_datetime in header
                $delivery_ts = isset($response_res['header']['delivery_datetime'])
                    ? intval($response_res['header']['delivery_datetime']) / 1000
                    : time();
    
                $currenttime     = date("H:i:s", $delivery_ts);
                $currenttimedate = date("Y-m-d H:i:s", $delivery_ts);
    
                // auto token number
                $todayDate = date("Y-m-d");
                $tdaytrx = $this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate'  and status=2");
                $token = isset($tdaytrx[0][0]['tkn']) ? $tdaytrx[0][0]['tkn'] + 1 : 1;
    
                // round values
                $finalamount = round($orders['Online_order']['total_amount']);
                $round_amount = $finalamount - $orders['Online_order']['total_amount'];
    
                $webhooks = $this->Online_order->find('all', ['conditions' => ['Online_order.reference_id' => $reference_id]]);
                
                $orderitems = [];
                $remarks = [];
                $total_tax_value = 0;
            
                foreach ($webhooks as $webhook) {
                    // Canonical JSON stored as array (not raw UP object format)
                    $response_obj = json_decode($webhook['Online_order']['response'], true);
                    $ordertxnid   = $webhook['Online_order']['reference_id'];
            
                    if (empty($response_obj['items'])) {
                        return json_encode(['status' => false, 'message' => "Missing order items for txn $ordertxnid"]);
                    }
                    
                    $delivery_ts = isset($response_obj['header']['delivery_datetime'])
                        ? intval($response_obj['header']['delivery_datetime']) / 1000
                        : time();
            
                    $currenttime     = date("H:i:s", $delivery_ts);
                    $currenttimedate = date("Y-m-d H:i:s", $delivery_ts);
                    
                    foreach ($response_obj['items'] as $item) {
                        $item_tax_value = 0;
                        $item_tax_rate  = 0;
            
                        if (!empty($item['taxes'])) {
                            foreach ($item['taxes'] as $tax) {
                                $item_tax_value += $tax['value'];
                                $item_tax_rate  += $tax['rate'];
                            }
                        }
                        $total_tax_value += $item_tax_value;
            
                        $ttlprice = ($item['unit_price'] * $item['qty']) - ($item['discount'] ?? 0);
                        
                        $orderitems[] = [
                            'id'                   => '',
                            'reference_id'         => $ordertxnid,
                            'cashier_id'           => '',
                            'group_id'             => '',
                            'category'             => $item['category_id']   ?? '0',
                            'category_name'        => $item['category_name'] ?? '',
                            'kds'                  => '',
                            'product_id'           => $item['merchant_id']   ?? '0',
                            'product_name'         => $item['name']          ?? '',
                            'quantity'             => strval($item['qty']        ?? '0'),
                            'price'                => strval($item['unit_price'] ?? '0'),
                            'total_tax'            => number_format(round($item_tax_value, 2), 2),
                            'total_tax_percentage' => strval($item_tax_rate),
                            'total_price'          => strval($ttlprice),
                            'discount'             => strval($item['discount'] ?? '0'),
                            'table_number'         => '0',
                            'remarks'              => '',
                            'status'               => '2',
                            'created'              => $currenttimedate
                        ];
                    }
                }
                
                $transactionitems[] = [
                    'id'                => $orders['Online_order']['id'],
                    'reference_id'      => $reference_id,
                    'orderno'           => $orders['Online_order']['order_id'],
                    'device_id'         => '0',
                    'cashier_id'        => $cashier_id??'0',
                    'table_number'      => '0',
                    'price'             => $orders['Online_order']['total_price'] ?? '0',
                    'total_tax'         => $orders['Online_order']['total_taxes'] ?? '0',
                    'servicecharge'     => '0',
                    'discount'          => isset($response_res['financials']['discount']) ? strval($response_res['financials']['discount']) : "0",
                    'discount_percentage' => '0',
                    'discount_type'     => '2',
                    'discount_type_value' => 'Flat',
                    'delivery_charge'   => '0',
                    'packing_charge'    => strval($total_pack_charge) ?? '0',
                    'amount'            => strval($finalamount) ?? '0',
                    'round'             => number_format($round_amount, 2, '.', ''), 
                    'name'              => $response_res['header']['customer']['name']         ?? '',
                    'phone'             => $response_res['header']['customer']['phone']        ?? '',
                    'address'           => $response_res['header']['customer']['address_city'] ?? '',
                    'remarks'           => $orders['Online_order']['remarks'] ?? '',
                    'status'            => strval($orders['Online_order']['status']),
                    'tokenno'           => "$token",
                    'createtime'        => $currenttime,
                    'created'           => $currenttimedate,
                    'payment_mode'      => $response_res['header']['channel'] ?? '',
                    'items'             => $orderitems
                ];
            }
        }
    
        // cashier name
        $cashier_name = '';
        $cashname = $this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if ($cashname && isset($cashname[0]['users']['name'])) {
            $cashier_name = $cashname[0]['users']['name'];
        }
    
        $response = [
            'status'       => true,
            'message'      => "success",
            'cashier_name' => $cashier_name,
            'transactions' => $transactionitems
        ];
    
        return json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }
    
    public function online_order_food_ready()
    {
        $cashierid    = isset($_REQUEST['id'])           ? $_REQUEST['id']           : '';
        $reference_id = isset($_REQUEST['reference_id']) ? $_REQUEST['reference_id'] : '';

        if ($cashierid == '') {
            return json_encode(array('status' => false, 'message' => "User Id Missing"));
        }

        $users = $this->User->find('first', array('conditions' => array('User.id' => $cashierid, 'User.status' => 1)));
        if (empty($users)) {
            return json_encode(array('status' => false, 'message' => "Cashier not found"));
        }

        if ($reference_id == '') {
            return json_encode(array('status' => false, 'message' => "Reference Id Missing"));
        }

        $webhook = $this->Online_order->find('first', array(
            'conditions' => array(
                'Online_order.reference_id' => $reference_id,
                'Online_order.status'       => 1
            )
        ));

        if (empty($webhook)) {
            return json_encode(array('status' => false, 'message' => "Order not found or not yet accepted"));
        }

        $upOrderId = $webhook['Online_order']['order_id'];

        // Push Food Ready to UrbanPiper
        $upresponse  = $this->order_status_change($upOrderId, "Food Ready", "Food packed at restaurant");
        $chkresponse = json_decode($upresponse, true);

        // Update local status to Food Ready (2) regardless of UP response
        $this->Online_order->updateAll(
            array('Online_order.status' => 2),
            array('Online_order.reference_id' => $reference_id)
        );

        if (!empty($chkresponse['status']) && $chkresponse['status'] == true) {
            return json_encode(array('status' => true, 'message' => "Food ready status updated"));
        } else {
            return json_encode(array('status' => true, 'message' => "Food ready marked locally; UP push: " . ($chkresponse['message'] ?? 'unknown')));
        }
    }
    
    function order_status_change($orderno=null,$status=null,$message=null)
    {
        $response=array();
        $response['status']=false;
        $response['message']="fail";
        $retry_attempt=0;
    
        // G6 fix: credentials moved to env vars — never hardcode in source.
        // Credentials moved to env vars. Rotate any old keys in UrbanPiper Hub.
        $upApiKey  = 'biz_adm_egGcwzZpmqZk';
        $upApiPass = '1dda18a8837267a9ae5d630ed67fe220f517b911';
        $upBaseUrl = 'https://api.urbanpiper.com';

        $data=array('new_status'=>$status,'message'=>$message);
        $data_post = json_encode($data);
        $url = $upBaseUrl . "/external/api/v1/orders/$orderno/status/";
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_post);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: apikey ' . $upApiKey . ':' . $upApiPass,
            'Content-Type: application/json'
        ));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        $output = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if (curl_errno($ch)) {
            $error = curl_error($ch);
            $response['message']=$error;
            die(json_encode($response));
        }
        curl_close($ch);
        if($httpcode>=500)
        {
            $error['status']="error";
            $error['message']=$httpcode." error";
            $output=json_encode($error);
        }

        if($httpcode==401)
        {
            $error['status']="error";
            $error['message']=$httpcode." error";
            $output=json_encode($error);
        }
            
        $result=json_decode($output,true);
        if(!empty($result) && $result['status']=='success')
        {
            $response['status']=true;
            $response['message']=$result['message'];
        }else{
            $response['message']=$result['message'];
        }
        return json_encode($response);
    }
    
    public function online_order_cancelled()
    {
        $cashierid    = isset($_REQUEST['id'])           ? $_REQUEST['id']           : '';
        $reference_id = isset($_REQUEST['reference_id']) ? $_REQUEST['reference_id'] : '';
        $current_state = isset($_REQUEST['status_code']) ? $_REQUEST['status_code']  : 'store_busy';

        if ($cashierid == '') {
            return json_encode(array('status' => false, 'message' => "User Id Missing"));
        }

        $users = $this->User->find('first', array('conditions' => array('User.id' => $cashierid, 'User.status' => 1)));
        if (empty($users)) {
            return json_encode(array('status' => false, 'message' => "Cashier not found"));
        }

        if ($reference_id == '') {
            return json_encode(array('status' => false, 'message' => "Reference Id Missing"));
        }

        $webhook = $this->Online_order->find('first', array(
            'conditions' => array('Online_order.reference_id' => $reference_id)
        ));

        if (empty($webhook)) {
            return json_encode(array('status' => false, 'message' => "Order not found"));
        }

        $upOrderId = $webhook['Online_order']['order_id'];

        // Void POS records if they exist
        $this->Order_orderhistory->updateAll(
            array('Order_orderhistory.status' => 0, 'Order_orderhistory.sync' => 0),
            array('Order_orderhistory.reference_id' => $reference_id)
        );
        $this->Order_tax->updateAll(
            array('Order_tax.status' => 0, 'Order_tax.sync' => 0),
            array('Order_tax.reference_id' => $reference_id)
        );
        $this->Order_transaction->updateAll(
            array('Order_transaction.status' => 0, 'Order_transaction.sync' => 0),
            array('Order_transaction.reference_id' => $reference_id)
        );
        $this->Order_payment->updateAll(
            array('Order_payment.status' => 0, 'Order_payment.sync' => 0),
            array('Order_payment.reference_id' => $reference_id)
        );

        // Mark online_order as cancelled (5)
        $this->Online_order->updateAll(
            array('Online_order.status' => 5, 'Online_order.sync' => 0, 'Online_order.local_sync' => 0),
            array('Online_order.reference_id' => $reference_id)
        );

        // Push Cancelled to UrbanPiper
        if (!empty($upOrderId)) {
            $cancelReasonMap = array(
                'item_out_of_stock'      => 'item_out_of_stock',
                'store_closed'           => 'store_closed',
                'store_busy'             => 'store_busy',
                'rider_not_available'    => 'rider_not_available',
                'out_of_delivery_radius' => 'out_of_delivery_radius',
                'connectivity_issue'     => 'connectivity_issue',
                'total_missmatch'        => 'total_missmatch',
                'invalid_item'           => 'invalid_item',
                'option_out_of_stock'    => 'option_out_of_stock',
                'invalid_option'         => 'invalid_option',
            );
            $reason = isset($cancelReasonMap[$current_state]) ? $cancelReasonMap[$current_state] : $current_state;
            $this->order_status_change($upOrderId, "Cancelled", $reason);
        }

        return json_encode(array('status' => true, 'message' => "Order cancelled"));
    }
    
    public function pos_status_update($reference_id)
    {
        $success = true;
    
        // Update Order_orderhistory
        // if (!$this->Order_orderhistory->updateAll(
        //     ['Order_orderhistory.status' => 0],
        //     ['Order_orderhistory.reference_id' => $reference_id]
        // )) {
        //     $success = false;
        // }
        if (!$this->Order_orderhistory->updateAll(
            array(
                'Order_orderhistory.status'     => 0,
                'Order_orderhistory.sync'       => 0,
                'Order_orderhistory.local_sync' => 0
            ),
            array(
                'Order_orderhistory.reference_id' => $reference_id
            )
        )) {
            $success = false;
        }

    
        // Update Order_tax
        if (!$this->Order_tax->updateAll(
            array(
                'Order_tax.status'     => 0,
                'Order_tax.sync'       => 0,
                'Order_tax.local_sync' => 0
            ),
            array(
                'Order_tax.reference_id' => $reference_id
            )
        )) {
            $success = false;
        }
        
        // Update Order_transaction
        if (!$this->Order_transaction->updateAll(
            array(
                'Order_transaction.status'     => 0,
                'Order_transaction.sync'       => 0,
                'Order_transaction.local_sync' => 0
            ),
            array(
                'Order_transaction.reference_id' => $reference_id
            )
        )) {
            $success = false;
        }
        
        // Update Order_payment
        if (!$this->Order_payment->updateAll(
            array(
                'Order_payment.status'     => 0,
                'Order_payment.sync'       => 0,
                'Order_payment.local_sync' => 0
            ),
            array(
                'Order_payment.reference_id' => $reference_id
            )
        )) {
            $success = false;
        }

        return $success;
    }
    
    public function online_order_notify()
    {
        $cashierid = $_REQUEST['id'];
        
        if ($cashierid == '') {
            return json_encode([
                'status' => false,
                'message' => "User Id Missing",
            ]);
        }
    
        $users = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1]
        ]);
        if (empty($users)) {
            return json_encode([
                'status' => false,
                'message' => "Cashier not found",
            ]);
        }
    
        if ($reference_id == '') {
            return json_encode([
                'status' => false,
                'message' => "Reference Id Missing",
            ]);
        }
    
        $store_id = $users['User']['location_id'];
    
        // Get order
        $webhook = $this->Online_order->find('first', [
            'conditions' => [
                'Online_order.store_id' => $store_id,
                'Online_order.notify' => 0,
                'Online_order.status' => 0
            ]
        ]);
    
        $success = $this->Online_order->updateAll(
            array(
                'Online_order.notify'     => 1,
                'Online_order.sync'       => 0,
                'Online_order.local_sync' => 0
            ),
            array(
                'Online_order.reference_id' => $webhook['Online_order']['reference_id']
            )
        );

        
        $response['status']=true;
        $response['title']="New Order Arrived!";
        $response['message']="Please Check!";
        
        return json_encode($response, JSON_UNESCAPED_UNICODE);
    }

    public function online_order_transaction_detail()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        if (empty($cashierid)) {
            return json_encode(['status' => false, 'message' => "User Id Missing"]);
        }
        if (empty($reference_id)) {
            return json_encode(['status' => false, 'message' => "Reference Id Missing"]);
        }
    
        $users = $this->User->find('first', ['conditions' => ['User.id' => $cashierid, 'User.status' => 1]]);
        if (empty($users)) {
            return json_encode(['status' => false, 'message' => "User not found"]);
        }
    
        $webhooks = $this->Online_order->find('all', ['conditions' => ['Online_order.reference_id' => $reference_id]]);
        
        $orderitems = [];
        $remarks = [];
        $total_tax_value = 0;
    
        foreach ($webhooks as $webhook) {
            $response = json_decode($webhook['Online_order']['response']);
            $txnid = $webhook['Online_order']['reference_id'];
    
            if (empty($response->order->items)) {
                return json_encode(['status' => false, 'message' => "Missing order items for txn $txnid"]);
            }
            
            $delivery_ts = isset($response->order->details->delivery_datetime)
                ? intval($response->order->details->delivery_datetime) / 1000
                : time();

            $currenttime     = date("H:i:s", $delivery_ts);
            $currenttimedate = date("Y-m-d H:i:s", $delivery_ts);
            
            
            foreach ($response->order->items as $item) {
                $item_tax_value = 0;
                $item_tax_rate = 0;
    
                if (!empty($item->taxes)) {
                    foreach ($item->taxes as $tax) {
                        $item_tax_value += $tax->value;
                        $item_tax_rate += $tax->rate;
                    }
                }
                $total_tax_value += $item_tax_value;
    
                $ttlprice = ($item->price * $item->quantity) - ($item->discount ?? 0);
                // timestamps
                
                $orderitems[] = [
                    'id'                   => '',
                    'reference_id'         => $txnid,
                    'cashier_id'           => '',
                    'group_id'             => '',
                    'category'             => isset($item->category->merchant_id) ? $item->category->merchant_id : '0',
                    'category_name'        => isset($item->category->name) ? $item->category->name : '',
                    'kds'                  => '',
                    'product_id'           => $item->merchant_id ?? '0',
                    'product_name'         => $item->title ?? '',
                    'quantity'             => strval($item->quantity) ?? '0',
                    'price'                => strval($item->price) ?? '0',
                    'total_tax'            => number_format(round($item_tax_value,2),2),
                    'total_tax_percentage' => strval($item_tax_rate),
                    'total_price'          => strval($ttlprice),
                    'discount'             => strval($item->discount) ?? '0',
                    'table_number'         => '0',
                    'remarks'              => '',
                    'status'               => '2',
                    'created'              =>  $currenttimedate
                ];
            }
        }
    
        return json_encode([
            'status'      => true,
            'message'     => "success",
            'cashier_name'=> '',
            'orders'      => $orderitems
        ]);
    }

    //kds
    
    public function reprint_data()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $orderitems=[];
        $order_punch_by='';
        
        $orderss = $this->Order_orderhistory->query("SELECT *,( SELECT name FROM users WHERE id = ( SELECT cashier_id FROM order_orderhistories WHERE reference_id = '$reference_id' AND status != 0 ORDER BY id ASC LIMIT 1 ) LIMIT 1 ) AS first_cashier_name   FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0");

        if(!empty($orderss))
        {
            
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $order_punch_by = $orders[0]['first_cashier_name'];
                
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                // 🔹 Get KOT numbers
                $kotQuery = $this->Order_orderhistory->query("
                    SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                    FROM order_orderhistories 
                    WHERE reference_id = '$reference_id' and status!=0
                ");
        
                $kot_numbers = '';
                if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                    $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                }
        
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'created' =>  $orders['Order_transaction']['created'],
                    'pax' =>  $orders['Order_transaction']['pax'],
                    'kot_number' => $kot_numbers
                );
            }
        }
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        // print_r($cashname);exit;
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'order_punch_by' => $order_punch_by,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function reprint_data_multistore()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $orderitems=[];
        $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0");
        // print_r("SELECT id,reference_id,group_id,cashier_id,category,category_name,product_id,product_name,SUM(quantity) as quantity,sum(price) as price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0 group BY product_id");exit;
        if(!empty($orderss))
        {
            
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'kot_number' => $orders['order_orderhistories']['kot_number'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->query(
            "SELECT GROUP_CONCAT(id) as id,reference_id,GROUP_CONCAT(orderno) as orderno,device_id,cashier_id,table_number,
            SUM(price) as price,SUM(total_tax) as total_tax,SUM(servicecharge) as servicecharge,SUM(discount) as discount,
            SUM(discount_type_value) as discount_type_value,SUM(delivery_charge) as delivery_charge,SUM(packing_charge) as packing_charge,
            SUM(amount) as amount,SUM(round) as round,discount_type ,name,phone,address,GROUP_CONCAT(remarks) as remarks,status,GROUP_CONCAT(tokenno) as tokenno,
            createtime,created,pax FROM `order_transactions` WHERE reference_id='$reference_id' and status!=0");
        
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                
                if(!$orders[0]['remarks']){
                    $orders[0]['remarks']='';
                }
                $finalamount=$orders[0]['amount'];
                $cashierid=$orders[0]['cashier_id'];
                $reference_id=$orders['order_transactions']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                 // 🔹 Get KOT numbers
                $kotQuery = $this->Order_orderhistory->query("
                    SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                    FROM order_orderhistories 
                    WHERE reference_id = '$reference_id' and status!=0
                ");
        
                $kot_numbers = '';
                if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                    $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                }
                
                $transactionitems[]=array(
                    'id' => $orders[0]['id'],
                    'reference_id' =>  $orders['order_transactions']['reference_id'],
                    'orderno' =>  $orders[0]['orderno'],
                    'device_id' =>  $orders['order_transactions']['device_id'],
                    'cashier_id' =>  $orders['order_transactions']['cashier_id'],
                    'table_number' =>  $orders['order_transactions']['table_number'],
                    'price' =>  number_format($orders[0]['price'],2),
                    'total_tax' =>  number_format($orders[0]['total_tax'],2),
                    'servicecharge' =>  $orders[0]['servicecharge'],
                    'discount' =>  $orders[0]['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['order_transactions']['discount_type'],
                    'discount_type_value' =>  $orders[0]['discount_type_value'],
                    'delivery_charge' =>  $orders[0]['delivery_charge'],
                    'packing_charge' =>  $orders[0]['packing_charge'],
                    'amount' =>  $orders[0]['amount'],
                    'round' =>  $orders[0]['round'],
                    'name' =>  $orders['order_transactions']['name'],
                    'phone' =>  $orders['order_transactions']['phone'],
                    'address' =>  $orders['order_transactions']['address'],
                    'remarks' =>  $orders['order_transactions']['remarks'],
                    'status' =>  $orders['order_transactions']['status'],
                    'tokenno' =>  $orders[0]['tokenno'],
                    'createtime' =>  $orders['order_transactions']['createtime'],
                    'pax' =>  $orders['order_transactions']['pax'],
                    'created' =>  $orders['order_transactions']['created'],
                    'kot_number' => $kot_numbers
                );
            }
        }
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function fetch_paymentdata_storeid()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('id'=>$reference_id,'status !='=>0)));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'created' =>  $orders['Order_transaction']['created']
                );
            }
        }
        else
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not found.",
            );
            return json_encode($response);
        }
        
        $reference_id=$transactions['Order_transaction']['reference_id'];
        $store_id=$transactions['Order_transaction']['store_id'];
        
        $orderitems=[];
        $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and store_id='$store_id' and status!=0");
        // print_r("SELECT id,reference_id,group_id,cashier_id,category,category_name,product_id,product_name,SUM(quantity) as quantity,sum(price) as price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0 group BY product_id");exit;
        if(!empty($orderss))
        {
            
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'store_id'=>$store_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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 store_id='$store_id' and status!=0 GROUP by tax_id");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and store_id='$store_id' and status!=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        // print_r($cashname);exit;
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function fetch_printdata_gstwise()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $orderitems=[];
        $order_punch_by='';
        
        $orderss = $this->Order_orderhistory->query("SELECT *,  ( SELECT name FROM users WHERE id = ( SELECT cashier_id FROM order_orderhistories WHERE reference_id = '$reference_id'  AND status != 0 ORDER BY id ASC LIMIT 1 ) LIMIT 1 ) AS first_cashier_name FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0");
        // print_r("SELECT id,reference_id,group_id,cashier_id,category,category_name,product_id,product_name,SUM(quantity) as quantity,sum(price) as price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0 group BY product_id");exit;
        if(!empty($orderss))
        {
            
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $order_punch_by = $orders[0]['first_cashier_name'];

                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->query(
            "SELECT GROUP_CONCAT(id) as id,reference_id,GROUP_CONCAT(orderno) as orderno,device_id,cashier_id,table_number,
            SUM(price) as price,SUM(total_tax) as total_tax,SUM(servicecharge) as servicecharge,SUM(discount) as discount,
            SUM(discount_type_value) as discount_type_value,SUM(delivery_charge) as delivery_charge,SUM(packing_charge) as packing_charge,
            SUM(amount) as amount,SUM(round) as round,discount_type ,name,phone,address,GROUP_CONCAT(remarks) as remarks,status,GROUP_CONCAT(tokenno) as tokenno,
            createtime,created,pax FROM `order_transactions` WHERE reference_id='$reference_id' and status!=0");
        
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                
                if(!$orders[0]['remarks']){
                    $orders[0]['remarks']='';
                }
                $finalamount=$orders[0]['amount'];
                $cashierid=$orders[0]['cashier_id'];
                $reference_id=$orders['order_transactions']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                // print_r("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status=2 and discount_percentage!=0 limit 1");exit;
                // 🔹 Get KOT numbers
                $kotQuery = $this->Order_orderhistory->query("
                    SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                    FROM order_orderhistories 
                    WHERE reference_id = '$reference_id' and status!=0
                ");
        
                $kot_numbers = '';
                if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                    $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                }
                
                $transactionitems[]=array(
                    'id' => $orders[0]['id'],
                    'reference_id' =>  $orders['order_transactions']['reference_id'],
                    'orderno' =>  $orders[0]['orderno'],
                    'device_id' =>  $orders['order_transactions']['device_id'],
                    'cashier_id' =>  $orders['order_transactions']['cashier_id'],
                    'cashier_name' => isset($users['User']['username']) ? $users['User']['username'] : '',
                    'table_number' =>  $orders['order_transactions']['table_number'],
                    'price' =>  number_format($orders[0]['price'],2),
                    'total_tax' =>  number_format($orders[0]['total_tax'],2),
                    'servicecharge' =>  $orders[0]['servicecharge'],
                    'discount' =>  $orders[0]['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['order_transactions']['discount_type'],
                    'discount_type_value' =>  $orders[0]['discount_type_value'],
                    'taxable_amount' => number_format(($orders[0]['price'] + $orders[0]['servicecharge']) - $orders[0]['discount'], 2),
                    'delivery_charge' =>  $orders[0]['delivery_charge'],
                    'packing_charge' =>  $orders[0]['packing_charge'],
                    'amount' =>  $orders[0]['amount'],
                    'round' =>  $orders[0]['round'],
                    'name' =>  $orders['order_transactions']['name'],
                    'phone' =>  $orders['order_transactions']['phone'],
                    'address' =>  $orders['order_transactions']['address'],
                    'remarks' =>  $orders['order_transactions']['remarks'],
                    'status' =>  $orders['order_transactions']['status'],
                    'tokenno' =>  $orders[0]['tokenno'],
                    'createtime' =>  $orders['order_transactions']['createtime'],
                    'pax' =>  $orders['order_transactions']['pax'],
                    'created' =>  $orders['order_transactions']['created'],
                    'kot_number' => $kot_numbers
                );
            }
        }
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status=2");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $brandsale=[];
        $brandsaless = $this->Order_transaction->query("SELECT store_id,(SELECT name from locations WHERE id=order_transactions.store_id) as brandname,(SELECT print_line4 from locations WHERE id=order_transactions.store_id) as brandgst,orderno,(SELECT GROUP_CONCAT(CONCAT(type_value, ' - ', amount)) from order_payments WHERE status=2 and reference_id=order_transactions.reference_id and store_id=order_transactions.store_id) as payment_mode FROM `order_transactions` WHERE reference_id='$reference_id' and status!=0 GROUP by store_id");
        if(!empty($brandsaless))
        {
            foreach($brandsaless as $brandsales){
                // print_r($brandsales);exit;
                
                $brandsale[]=array(
                   'store_id'     => $brandsales['order_transactions']['store_id'] ?? '',
                'brandname'    => $brandsales[0]['brandname'] ?? '',
                'brandgst'     => $brandsales[0]['brandgst'] ?? '',
                'orderno'      => $brandsales['order_transactions']['orderno'] ?? '',
                'payment_mode' => $brandsales[0]['payment_mode'] ?? ''
                );
            }
        }
        
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'order_punch_by'=>$order_punch_by,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'brandsale'=>$brandsale,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function table_view_edit()
    {
        $this->autoRender = false;
        $user_id = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
        $reference_id = isset($_REQUEST['reference_id']) ? $_REQUEST['reference_id'] : '';
        $today = date("Y-m-d");
        //reference id 

        $startdate = date("Y-m-d");
        $enddate   = date("Y-m-d");
        
        // build shift-based datetime
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        if (empty($reference_id)) {
            return json_encode(['status' => false, 'message' => "Reference Id Missing"]);
        }
    
        // Fetch KDS stations once
        $kds_stations = $this->Kds_users_station_mapping->find('all', [
            'conditions' => [
                'Kds_users_station_mapping.status' => 1
            ],
            'group' => ['Kds_users_station_mapping.station_id'],
            'recursive' => -1
        ]);

        if (empty($kds_stations)) {
            return json_encode(['status' => false, 'message' => "No KDS stations assigned"]);
        }
    
        $stations_id = array();
        $stations_map = array();
        foreach ($kds_stations as $s) {
            $station = $s['Kds_users_station_mapping'];
            $stations_id[] = $station['station_id'];
            $stations_map[$station['station_id']] = array(
                'station_id' => $station['station_id'],
                'station_name' => $station['station_name'],
                'station_store_id' => $station['station_store_id'],
                'station_store_name' => $station['station_store_name'],
                'items' => array()
            );
        }
    
        if (empty($stations_id)) {
            $stations_id = array(0);
        }
    
        // Fetch all orders for today for these stations
        $orders_raw = $this->Order_orderhistory->find('all', [
            'conditions' => array(
                'Order_orderhistory.created >=' => $startDatetime,
                'Order_orderhistory.created <=' => $endDatetime,
                'Order_orderhistory.status !=' => 0,
                'Order_orderhistory.kds' => $stations_id,
                'Order_orderhistory.reference_id' => $reference_id
            ),
            'fields' => array(
                'Order_orderhistory.*',
                'Order_table.waiter_name',
                'GROUP_CONCAT(DISTINCT Order_orderhistory.kot_number ORDER BY Order_orderhistory.kot_number SEPARATOR ", ") AS kot_numbers'
            ),
            'joins' => array(
                array(
                    'table' => 'order_tables',
                    'alias' => 'Order_table',
                    'type' => 'LEFT',
                    'conditions' => array('Order_table.reference_id = Order_orderhistory.reference_id')
                )
            ),
            'group' => array('Order_orderhistory.reference_id', 'Order_orderhistory.group_id'),
            'order' => ['Order_orderhistory.id DESC'],  // ðŸ‘ˆ Added order by
            'limit' => 10,   //  Added limit here
            'recursive' => -1
        ]);
    
        if (empty($orders_raw)) {
            return json_encode(array('status' => false, 'message' => "No Order found"));
        }
    
        // Collect all reference_ids
        $reference_ids = array();
        foreach ($orders_raw as $o) {
            $reference_ids[] = $o['Order_orderhistory']['reference_id'];
            $group_ids[] = $o['Order_orderhistory']['group_id'];
        }
    
        $order_items_raw = $this->Order_orderhistory->find('all', array(
            'conditions' => array(
                'Order_orderhistory.status !=' => 0,
                'Order_orderhistory.created >=' => $startDatetime,
                'Order_orderhistory.created <=' => $endDatetime,
                'Order_orderhistory.reference_id' => $reference_ids,
                'Order_orderhistory.group_id' => $group_ids,
                'Order_orderhistory.kds' => $stations_id
            ),
            'fields' => array(
                'Order_orderhistory.*',
                'Catalog_product.preparation_time'
            ),
            'joins' => array(
                array(
                    'table' => 'catalog_product',
                    'alias' => 'Catalog_product',
                    'type' => 'LEFT',
                    'conditions' => array('Catalog_product.id = Order_orderhistory.product_id')
                )
            ),
            'recursive' => -1
        ));
    
        // Fetch all modifiers in bulk
        $order_items_ids = array();
        foreach ($order_items_raw as $oi) {
            $order_items_ids[] = $oi['Order_orderhistory']['id'];
        }
    
        $modifiers_raw = array();
        if (!empty($order_items_ids)) {
            $modifiers_raw = $this->Order_modifier->find('all', array(
                'conditions' => array(
                    'Order_modifier.orderhistory_id' => $order_items_ids,
                    'Order_modifier.status !=' => 0
                ),
                'recursive' => -1
            ));
        }
    
        // Map modifiers by orderhistory_id
        $modifiers_map = array();
        foreach ($modifiers_raw as $mod) {
            $m = $mod['Order_modifier'];
            $modifiers_map[$m['orderhistory_id']][] = array(
                'modifier_group_id' => $m['modifier_group_id'],
                'modifier_group_name' => $m['modifier_group_name'],
                'modifier_id' => $m['modifier_id'],
                'modifier_name' => $m['modifier_name'],
                'modifier_price' => $m['modifier_price']
            );
        }
    
        // Organize items under stations and references
        $orders = array();
        foreach ($orders_raw as $order) {
            $order_data = $order['Order_orderhistory'];
            $reference_id = $order_data['reference_id'];
            $group_id = $order_data['group_id'];
            $kotNumbers = $order[0]['kot_numbers'];  // from the custom SQL field
            
            $stations = array();
            foreach ($stations_map as $station_id => $station_data) {
                $items = array();
                foreach ($order_items_raw as $oi) {
                    $oi_data = $oi['Order_orderhistory'];
                    if ($oi_data['reference_id'] == $reference_id && $oi_data['kds'] == $station_id && $oi_data['group_id'] == $group_id ) {
                        
                        
                        $kds_last_details = $this->Kds_track->find('first', [
                            'conditions' => [
                                'Kds_track.order_reference_id' => $reference_id,
                                'Kds_track.kds_group_id'       => $group_id,
                                'Kds_track.product_id'         => $oi_data['product_id'],
                                'Kds_track.status'             => 1
                            ],
                            'order'     => ['Kds_track.id' => 'DESC'], // latest record
                            'recursive' => -1
                        ]);
                        
                        if (empty($kds_last_details)) {
                            $kds_time = $oi_data['created'];
                        } else {
                            $kds_time = $kds_last_details['Kds_track']['created'];
                        }

                        $items[] = array(
                            'order_history_id' => $oi_data['id'],
                            'group_id' => $oi_data['group_id'],
                            'item_id' => $oi_data['product_id'],
                            'quantity' => $oi_data['quantity'],
                            'item_name' => $oi_data['product_name'],
                            'kds_status' => $oi_data['kds_status'],
                            'kds_status_update_at' => $kds_time,
                            'remarks' => $oi_data['remarks'],
                            'prep_time' => strval(isset($oi['Catalog_product']['preparation_time']) ? $oi['Catalog_product']['preparation_time'] : '0'),
                            'modifiers' => isset($modifiers_map[$oi_data['id']]) ? $modifiers_map[$oi_data['id']] : array()
                        );
                    }
                }
                $station_data['items'] = $items;
                if($station_data['items']){
                    $stations[] = $station_data;
                }
            }
            
            if($order_data['table_number']){
                $table_number=$order_data['table_number'];
            }else{
                $table_number='Quick Order';
            }
    
            $orders[] = array(
                'kds_ref_id' => $reference_id,
                'kds_group_id' => $group_id,
                'table_no' => $table_number,
                'kot_number' => $kotNumbers,
                'created' => $order_data['created'],
                'waiter_name' => isset($order['Order_table']['waiter_name']) ? $order['Order_table']['waiter_name'] : '',
                'kds_status' => $order_data['kds_status'],
                'stations' => $stations
            );
        }
    
        return json_encode(array('status' => true, 'orders' => $orders), JSON_UNESCAPED_UNICODE);
    }
    
    public function payment_mode_update()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $reference_id = $_REQUEST['reference_id'];
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id is Missing",
            );
            return json_encode($response);
        }
        
        $payment_type = $_REQUEST['type'];
        if($payment_type==''){
            $response =array(
                'status'=> false,
                'message'=> "Payment type is Missing",
            );
            return json_encode($response);
        }
        
        $payment_type_value = $_REQUEST['type_value'];
        if($payment_type_value==''){
            $response =array(
                'status'=> false,
                'message'=> "Payment type Value is Missing",
            );
            return json_encode($response);
        }
        
        $amount = $_REQUEST['amount'];
        if($amount==''){
            $response =array(
                'status'=> false,
                'message'=> "Payment Amount is Missing",
            );
            return json_encode($response);
        }
        
        $device_id=$_REQUEST['device_id'];
        $remarks='';
        $remarks=$_REQUEST['remarks'];
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        //payment save
        
        $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status'=>2)));
        if(empty($transactions))
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not billed",
            );
            return json_encode($response);
        }
        $reference_id=$transactions['Order_transaction']['reference_id'];
        $total_amount=$transactions['Order_transaction']['amount'];
        $store_id=$transactions['Order_transaction']['store_id'];
        if($amount>=$total_amount){
            $this->Order_payment->query("UPDATE order_payments SET status = 0,sync=0,local_sync=0 WHERE reference_id = '$reference_id'");
                                
            $datas['Order_payment']=array(
                'reference_id'=>$reference_id,
                'device_id'=>$device_id,
                'store_id'=>$store_id,
                'cashier_id'=>$cashierid,
                'type'=>$payment_type,
                'type_value'=>$payment_type_value,
                'amount'=>$amount,
                'remarks'=>$remarks,
                'status'=>2
            );
            
            if($this->Order_payment->saveAll($datas['Order_payment']))
            {
                $response['status']= true;
                $response['message']= "Payment Mode Updated Successfully..!";
            }else{
                $response['status']= false;
                $response['message']= "Payment Mode not Saved..!";
            }
        }else{
            $response['status']= false;
            $response['message']= "Update Failed !! Payment Mode Update Can't accept Partial payments..!!";
        }
        return json_encode($response);
    }
    
    public function bill_preview()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id=$_REQUEST['reference_id'];
        $disc=0;
        $sc = servicecharge;
        $type = 1;
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        
        $todayDate = date("Y-m-d");
        
        $ref_id = [$ref_id]; // convert initial ref id to array

        $refid = []; // T9-fix: ensure $refid is always an array even with no merged tables

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $ref_id[0],
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $ref_id[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        $ref_in = "'" . implode("','", $ref_id) . "'";
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$disc,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
                if(empty($coup))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Coupon not found Or Coupon Expired",
                    );
                    return json_encode($response);
                }
                $disc=$coup['Coupon']['value'];
            }else{
                $disc=0;
            }
        }
        
        if($type==1){
            $disc=$disc;
        }
        
        if($type==2){
            $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id IN ($ref_in)");
            
            if($subtotals){
                $subtotal=$subtotals[0][0]['subtotal'];
                if($subtotal){
                    $disc=(($disc*100)/$subtotal);
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    );
                    return json_encode($response);
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Bill Not Found",
                );
                return json_encode($response);
            }
        }
        
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.cashier_id'=>$cashierid,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id IN'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        $orderdata=$this->ordercomputewithdiscounttemp($ref_id,$cashierid,$sc,$disc);
            
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            //print_r($totalamount);exit;
            
            $orderitems=[];
            $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,SUM(quantity) as quantity,price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id IN ($ref_in) and status!=0 group BY product_id");
            if(!empty($orderss))
            {
                foreach($orderss as $orders){
                    if(!isset($orders['order_orderhistories']['remarks'])){
                        $orders['order_orderhistories']['remarks']='';
                    }
                    
                    $taxesitems=[];
                    $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$orders['order_orderhistories']['product_id'],'Catalog_product_tax.status'=>1)));
                    foreach($taxess as $tax){
                        $taxesitems[]=array(
                            'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                            'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                            'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                        );
                    }
                    
                    $orderitems[]=array(
                        'id' => $orders['order_orderhistories']['id'],
                        'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                        'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                        'group_id' =>  $orders['order_orderhistories']['group_id'],
                        'category' =>  $orders['order_orderhistories']['category'],
                        'category_name' =>  $orders['order_orderhistories']['category_name'],
                        'kds' =>  $orders['order_orderhistories']['kds'],
                        'product_id' =>  $orders['order_orderhistories']['product_id'],
                        'product_name' =>  $orders['order_orderhistories']['product_name'],
                        'quantity' =>  $orders[0]['quantity'],
                        'price' =>  $orders['order_orderhistories']['price'],
                        'total_tax' =>  $orders[0]['total_tax'],
                        'total_price' =>  $orders[0]['total_price'],
                        'discount' =>  $orders[0]['discount'],
                        'table_number' =>  $orders['order_orderhistories']['table_number'],
                        'remarks' =>  $orders['order_orderhistories']['remarks'],
                        'status' =>  $orders['order_orderhistories']['status'],
                        'created' =>  $orders['order_orderhistories']['created'],
                        'taxes'=>$taxesitems
                    );
                }
            }
            $tablenomb=0;
            $tableno=$this->Order_table->query("SELECT GROUP_CONCAT(number) as tbale FROM `order_tables` WHERE status!=0 and reference_id IN ($ref_in)");
            if($tableno){
               $tablenomb =$tableno[0][0]['tbale'];
            }
            
            $finalamount=0;
            $transactionitems=[];
            $createtime = date('H:i:s');
            $transactionitems[]=array(
                'id' => '',
                'reference_id' =>  $ref_in,
                'orderno' =>  '',
                'device_id' =>  '',
                'cashier_id' =>  $cashierid,
                'table_number'        => (string) $tablenomb,
                'price'               => (string) number_format($totalprice, 2), // optional 2 decimals
                'total_tax'           => (string) round($totaltax, 2),
                'servicecharge'       => (string) $totalservicechg,
                'discount'            => (string) $totaldiscount,
                'discount_percentage' => (string) $disc,
                'delivery_charge'     => '0',
                'packing_charge'      => '0',
                'amount'              => (string) round($totalamount, 2),
                'round'               => '0',
                'name' =>  '',
                'phone' =>  '',
                'address' => '',
                'remarks' =>  '',
                'status' =>  '',
                'tokenno' =>  '',
                'createtime' =>  $createtime,
                'created' =>  ''
            );
            
            $paymentitems=[];
            
            $taxitems=[];
            $taxess=$orderdata['taxes'];
            foreach($taxess as $tax){
                $taxitems[]=array(
                    'tax_id' => $tax['tax_id'],
                    'tax_name' =>  $tax['tax_name'],
                    'tax_percentage' =>  $tax['tax_percentage'],
                    'tax_value' =>  number_format($tax['tax_value'],1)
                );
            }
                
            $amount_diff=0;
            
            $cashier_name='';
            $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
            if($cashname){
               $cashier_name =$cashname[0]['users']['name'];
            }
            // print_r($cashname);exit;
            
            $printeritems=[];
            $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
            if(!empty($printerss))
            {
                foreach($printerss as $printers){
                    // print_r($tax);exit;
                    
                    $printeritems[]=array(
                        'id' => $printers['pos_printers']['id'],
                        'store_id' =>  $printers['pos_printers']['store_id'],
                        'name' =>  $printers['pos_printers']['name'],
                        'kds' =>  $printers['pos_printers']['kds'],
                        'ip' =>  $printers['pos_printers']['ip'],
                        'status' =>  $printers['pos_printers']['status']
                    );
                }
            }
            
            
            $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>(string) round($totalamount, 2)
            );
            
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "No data found",
            );
            return json_encode($response);
        }
    }
    
    public function ordercomputewithdiscounttemp($txnids=null,$user_id=null,$is_sc=1,$discount=0)
    {
        $response['status']=false;
        $totalservicechg=0;
        $totalprice=0;
        $totaltax1=0;
        $totaltax2=0;
        $totaldiscount=0;
        $sc=0;
        
        if (!is_array($txnids)) {
            $txnids = [$txnids];
        }
        if($is_sc==1){
            $sc=servicecharge;
        }
        $discq="(((Order_orderhistory.total_price)-(Order_orderhistory.discount))*$discount/100)";
        $priceq="((Order_orderhistory.total_price)-(Order_orderhistory.discount))";
    
        $this->Order_orderhistory->virtualFields = array('tdisc'=>"SUM($discq)",'tservicechg'=>"SUM(($priceq-$discq)*($sc/100))",'tprice'=>"SUM($priceq)",'total_tax'=>"SUM(($priceq+(($priceq-$discq)*($sc/100))-$discq)*((Order_orderhistory.total_tax_percentage)/100))");  
        
        $orderhistories=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.reference_id IN'=>$txnids,'Order_orderhistory.status !=' =>0),'fields'=>array('tdisc','Order_orderhistory.reference_id','tprice','total_tax','tservicechg')));
                
        if(!empty($orderhistories)){
            $response['status']=true;
            $totalservicechg=round($orderhistories['Order_orderhistory']['tservicechg'],2);
            $totalprice=round($orderhistories['Order_orderhistory']['tprice'],2);
            $totaltax=round($orderhistories['Order_orderhistory']['total_tax'],2);
            $totaldiscount=round($orderhistories['Order_orderhistory']['tdisc'],2);
            
            //tax update
            $discq="(((Order_orderhistory.price)-(Order_orderhistory.discount))*$discount/100)";
            $priceq="((Order_orderhistory.price)-(Order_orderhistory.discount))";
            
            $taxes=[];
            
            $this->Order_orderhistory->virtualFields = array('tamount'=>"($priceq+(($priceq-$discq)*($sc/100))-$discq)");  
            $neworderhistories=$this->Order_orderhistory->find('all',array('conditions'=>array('Order_orderhistory.reference_id IN'=>$txnids,'Order_orderhistory.cashier_id'=>$user_id,'Order_orderhistory.status !='=>0),'fields'=>array('Order_orderhistory.reference_id','tamount','product_id','price')));
            foreach($neworderhistories as $data){
                $reference_id=$data['Order_orderhistory']['reference_id'];
                $product_id=$data['Order_orderhistory']['product_id'];
                $tamount=$data['Order_orderhistory']['tamount'];
                $price=$data['Order_orderhistory']['price'];
                
                $taxitem=$this->Order_tax->find('all',array('conditions'=>array('Order_tax.reference_id IN'=>$txnids,'Order_tax.product_id'=>$product_id,'Order_tax.status !='=>0)));
                foreach($taxitem as $item){
                    $id=$item['Order_tax']['id'];
                    $tax_id=$item['Order_tax']['tax_id'];
                    $tax_percentage=$item['Order_tax']['tax_percentage'];
                    $quantity=$item['Order_tax']['quantity'];
                    $taxamount=round($tamount*$quantity,2);
                    $taxvalue=round((($tamount*$quantity*$tax_percentage)/100),2);
                    
                    if (isset($taxes[$tax_id])) {
                        $taxes[$tax_id]['tax_value'] += round($taxvalue, 2);
                    } else {
                        // Add new entry if tax_id doesn't exist
                        $taxes[$tax_id] = array(
                            'id' => $id,
                            'tax_id' =>  $item['Order_tax']['tax_id'],
                            'tax_name' => $item['Order_tax']['tax_name'],
                            'tax_percentage' => $tax_percentage,
                            'tax_value' => number_format($taxvalue, 2)
                        );
                    }
                }
            }
            
            $response['totalservicechg']=$totalservicechg;
            $response['totalprice']=$totalprice;
            $response['totaltax']=$totaltax;
            $response['totaldiscount']=$totaldiscount;
            $response['taxes']=$taxes;
        }
        // print_r($response);exit;
        return $response;
    }
    
    public function bill_table_package()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['customer_pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];

        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'          => 0,
                'Order_table.local_sync'    => 0        
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
            
        $refid = []; // T9-fix: ensure $refid is always an array even with no merged tables

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                
                $round_amount = $finalamount - $roundfinalamount;
                
                $datas['Order_transaction']=array(
                    'reference_id'=>$table_referenceid,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'store_id'=>$location_id,
                    'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                    'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                    'discount'=>round($orderss[0][0]['discount'],2),
                    'amount'=>$finalamount,
                    'round'=>round($round_amount,2),
                    'name'=>$name,
                    'phone'=>$phone,
                    'address'=>$address,
                    'tokenno'=>$token,
                    'table_number'=>$table_number,
                    'pax'=>$pax,
                    'waiter_id'=>$waiter_id,
                    'waiter_name'=>$waiter_name,
                    'is_takeaway' => $is_takeaway,
                    'createtime'=>$currenttime
                );
                if($this->Order_transaction->saveAll($datas['Order_transaction']))
                {
                    $this->Order_table->query("UPDATE order_tables SET status = 3,sync=0,local_sync=0 WHERE reference_id = '$table_referenceid' and status!=0");
                    $this->Order_table->query("UPDATE order_tables SET status = 1,sync=0,local_sync=0 WHERE reference_id IN ($refid)  and status!=0");
                    $this->Order_table_tracking->query("UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0 WHERE merged_table_ref_id IN ($refid)");
            
                    $response['status']= true;
                    $response['message']= "Bill Generated Successfully..!";
                }else{
                    $response['status']= false;
                    $response['message']= "Transaction Data not saved Error:103";
                }
            }
        
        return json_encode($response);
    }
    
    public function custom_quantity_update()
    {
        $this->autoRender = false;
    
        $response = ['status' => false, 'message' => 'Failed'];
    
        // ✅ Safely read inputs
        $cashierid    = isset($_REQUEST['id']) ? trim($_REQUEST['id']) : '';
        $reference_id = isset($_REQUEST['reference_id']) ? trim($_REQUEST['reference_id']) : '';
        $quantity     = isset($_REQUEST['quantity']) ? trim($_REQUEST['quantity']) : '';
        $order_id     = isset($_REQUEST['order_id']) ? trim($_REQUEST['order_id']) : '';
    
        // ✅ Input validation
        if ($cashierid === '') {
            return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        }
        if ($reference_id === '') {
            return json_encode(['status' => false, 'message' => 'Reference ID is missing']);
        }
        if ($quantity === '' || !is_numeric($quantity) || $quantity <= 0) {
            return json_encode(['status' => false, 'message' => 'Quantity is missing or invalid']);
        }
        if ($order_id === '') {
            return json_encode(['status' => false, 'message' => 'Order ID is missing']);
        }
    
        // ✅ Check if user exists
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive' => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
    
        // ✅ Check if table exists
        $table = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $reference_id,
                'Order_table.status' => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($table)) {
            return json_encode(['status' => false, 'message' => 'Table not available for quantity update']);
        }
    
        // ✅ Fetch existing order
        $data = $this->Order_orderhistory->find('first', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $reference_id,
                'Order_orderhistory.status !=' => 0,
                'Order_orderhistory.id' => (int)$order_id
            ],
            'recursive' => -1
        ]);
    
        if (empty($data)) {
            return json_encode(['status' => false, 'message' => 'Order not available for quantity update']);
        }
    
        // ✅ Calculate new total
        $price = (float)$data['Order_orderhistory']['price'];
        $total_price = $price * (int)$quantity;
    
        // ✅ Initialize tax accumulator
        $tax = 0;
    
        // ✅ Fetch and update tax records
        $taxdatas = $this->Order_tax->find('all', [
            'conditions' => [
                'Order_tax.reference_id' => $reference_id,
                'Order_tax.orderhistory_id' => (int)$order_id,
                'Order_tax.status !=' => 0
            ],
            'recursive' => -1
        ]);
    
        if (!empty($taxdatas)) {
            foreach ($taxdatas as $taxdata) {
                $tax_percentage = (float)$taxdata['Order_tax']['tax_percentage'];
                $tax_value = ($total_price * $tax_percentage) / 100;
                $tax += $tax_value;
    
                $this->Order_tax->updateAll(
                    [
                        'Order_tax.quantity' => (int)$quantity,
                        'Order_tax.taxable_price' => round($total_price,2),
                        'Order_tax.tax_value' => round($tax_value,2),
                        'Order_tax.sync'            => 0,
                        'Order_tax.local_sync'      => 0
                    ],
                    [
                        'Order_tax.id' => (int)$taxdata['Order_tax']['id']
                    ]
                );
            }
        }
    
        // ✅ Update order history (quantity, total tax, total price)
        $updated = $this->Order_orderhistory->updateAll(
            [
                'Order_orderhistory.quantity'     => (int)$quantity,
                'Order_orderhistory.total_tax'    => round($tax,2),
                'Order_orderhistory.total_price'  => round($total_price,2),
                'Order_orderhistory.sync'         => 0,
                'Order_orderhistory.local_sync'   => 0
            ],
            [
                'Order_orderhistory.reference_id' => $reference_id,
                'Order_orderhistory.id'           => (int)$order_id,
                'Order_orderhistory.status !='    => 0
            ]
        );
    
        if ($updated) {
            $response = ['status' => true, 'message' => 'Quantity and tax updated successfully'];
        } else {
            $response = ['status' => false, 'message' => 'Quantity not updated'];
        }
    
        return json_encode($response);
    }
    
    public function item_move()
    {
        $this->autoRender = false;
    
        $response = ['status' => false, 'message' => 'Failed'];
    
        // ✅ Safely read inputs
        $cashierid    = isset($_REQUEST['id']) ? trim($_REQUEST['id']) : '';
        $order_id     = isset($_REQUEST['order_id']) ? trim($_REQUEST['order_id']) : '';
        $from_reference_id = isset($_REQUEST['from_reference_id']) ? trim($_REQUEST['from_reference_id']) : '';
        $to_reference_id = isset($_REQUEST['to_reference_id']) ? trim($_REQUEST['to_reference_id']) : '';
        
        // ✅ Input validation
        if ($cashierid === '') {
            return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        }
        if ($order_id === '') {
            return json_encode(['status' => false, 'message' => 'Order ID is missing']);
        }
        if ($from_reference_id === '') {
            return json_encode(['status' => false, 'message' => 'From Reference ID is missing']);
        }
        if ($to_reference_id === '') {
            return json_encode(['status' => false, 'message' => 'To Reference ID is missing']);
        }
    
        // ✅ Check if user exists
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive' => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
    
        // ✅ Check if table exists
        $fromtable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $from_reference_id,
                'Order_table.status' => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($fromtable)) {
            return json_encode(['status' => false, 'message' => 'From Table not available for Item Move']);
        }
        
        $totable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $to_reference_id,
                'Order_table.status' => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($totable)) {
            return json_encode(['status' => false, 'message' => 'To Table not available for Item Receive']);
        }
    
        // ✅ Fetch existing order
        $data = $this->Order_orderhistory->find('first', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $from_reference_id,
                'Order_orderhistory.status !=' => 0,
                'Order_orderhistory.id' => (int)$order_id
            ],
            'recursive' => -1
        ]);
    
        if (empty($data)) {
            return json_encode(['status' => false, 'message' => 'Item Not available for movement']);
        }
        

        // ✅ Move tax records for that item
        // $this->Order_tax->updateAll(
        //     [
        //         'Order_tax.reference_id' => "'$to_reference_id'"
        //     ],
        //     [
        //         'Order_tax.orderhistory_id' => (int)$order_id,
        //         'Order_tax.reference_id' => $from_reference_id,
        //         'Order_tax.status NOT' => 0
        //     ]
        // );
        $this->Order_tax->updateAll(
            array(
                'Order_tax.reference_id' => "'$to_reference_id'",
                'Order_tax.sync'         => 0,
                'Order_tax.local_sync'   => 0
            ),
            array(
                'Order_tax.orderhistory_id' => (int)$order_id,
                'Order_tax.reference_id'    => $from_reference_id,
                'Order_tax.status !='       => 0
            )
        );
    
        // ✅ Move item (order history)
        // $updated = $this->Order_orderhistory->updateAll(
        //     [
        //         'Order_orderhistory.reference_id' => "'$to_reference_id'",
        //         'Order_orderhistory.table_number' => "'".$totable['Order_table']['number']."'"
        //     ],
        //     [
        //         'Order_orderhistory.id' => (int)$order_id,
        //         'Order_orderhistory.reference_id' => $from_reference_id,
        //         'Order_orderhistory.status NOT' => 0
        //     ]
        // );
        $updated = $this->Order_orderhistory->updateAll(
            array(
                'Order_orderhistory.reference_id' => "'$to_reference_id'",
                'Order_orderhistory.table_number' => "'".$totable['Order_table']['number']."'",
                'Order_orderhistory.sync'         => 0,
                'Order_orderhistory.local_sync'   => 0
            ),
            array(
                'Order_orderhistory.id'            => (int)$order_id,
                'Order_orderhistory.reference_id'  => $from_reference_id,
                'Order_orderhistory.status !='     => 0
            )
        );
    
        if ($updated) {
            
            // Update KDS tracks for the moved item
            $this->Kds_track->updateAll(
                array(
                    'Kds_track.order_reference_id' => "'$to_reference_id'",
                    'Kds_track.table_no' => "'".$totable['Order_table']['number']."'",
                    'Kds_track.sync' => 0,
                    'Kds_track.local_sync' => 0
                ),
                array(
                    'Kds_track.order_history_id' => (int)$order_id,
                    'Kds_track.order_reference_id' => $from_reference_id,
                    'Kds_track.status !=' => 0
                )
            );
            
            // Update modifier reference
            $this->Order_modifier->updateAll(
                array(
                    'Order_modifier.reference_id' => "'$to_reference_id'",
                    'Order_modifier.sync' => 0,
                    'Order_modifier.local_sync' => 0
                ),
                array(
                    'Order_modifier.orderhistory_id' => (int)$order_id,
                    'Order_modifier.reference_id' => $from_reference_id,
                    'Order_modifier.status !=' => 0
                )
            );

            $response = ['status' => true, 'message' => 'Item Moved successfully'];
        } else {
            $response = ['status' => false, 'message' => 'Item Not Moved'];
        }
    
        return json_encode($response);
    }
    
    public function kot_move()
    {
        $this->autoRender = false;
    
        $response = ['status' => false, 'message' => 'Failed'];
    
        // ✅ Input parameters
        $cashierid = isset($_REQUEST['id']) ? trim($_REQUEST['id']) : '';
        $group_id = isset($_REQUEST['group_id']) ? trim($_REQUEST['group_id']) : '';
        $from_reference_id = isset($_REQUEST['from_reference_id']) ? trim($_REQUEST['from_reference_id']) : '';
        $to_reference_id = isset($_REQUEST['to_reference_id']) ? trim($_REQUEST['to_reference_id']) : '';
    
        // ✅ Input validation
        if ($cashierid === '') return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        if ($group_id === '') return json_encode(['status' => false, 'message' => 'Group ID is missing']);
        if ($from_reference_id === '') return json_encode(['status' => false, 'message' => 'From Reference ID is missing']);
        if ($to_reference_id === '') return json_encode(['status' => false, 'message' => 'To Reference ID is missing']);
    
        // ✅ Validate user
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive' => -1
        ]);
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
    
        // ✅ Validate tables
        $fromtable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $from_reference_id,
                'Order_table.status' => 2
            ],
            'recursive' => -1
        ]);
        if (empty($fromtable)) {
            return json_encode(['status' => false, 'message' => 'From Table not available for Item Move']);
        }
    
        $totable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $to_reference_id,
                'Order_table.status' => 2
            ],
            'recursive' => -1
        ]);
        if (empty($totable)) {
            return json_encode(['status' => false, 'message' => 'To Table not available for Item Receive']);
        }
        
        // ✅ Fetch items belonging to that group
        $datas = $this->Order_orderhistory->find('all', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $from_reference_id,
                'Order_orderhistory.status !=' => 0,
                'Order_orderhistory.group_id' => $group_id
            ],
            'recursive' => -1
        ]);
        if (empty($datas)) {
            return json_encode(['status' => false, 'message' => 'No items found for this group']);
        }
    
        $movedCount = 0;
    
        // ✅ Start transaction for consistency
        $dataSource = $this->Order_orderhistory->getDataSource();
        $dataSource->begin();
    
        try {
            foreach ($datas as $data) {
                $order_id = $data['Order_orderhistory']['id'];
    
                // ✅ Move related tax entries
                $this->Order_tax->updateAll(
                    [
                        'Order_tax.reference_id' => "'$to_reference_id'",
                        'Order_tax.sync'         => 0,
                        'Order_tax.local_sync'   => 0
                    ],
                    [
                        'Order_tax.orderhistory_id' => (int)$order_id,
                        'Order_tax.reference_id'    => $from_reference_id,
                        'Order_tax.status !='      => 0
                    ]
                );

    
                // ✅ Move item to new reference
                $success = $this->Order_orderhistory->updateAll(
                    ['Order_orderhistory.reference_id' => "'$to_reference_id'",
                     'Order_orderhistory.table_number' => "'".$totable['Order_table']['number']."'",
                     'Order_orderhistory.sync'         => 0,
                     'Order_orderhistory.local_sync'   => 0
                    ],
                    [
                        'Order_orderhistory.id' => (int)$order_id,
                        'Order_orderhistory.reference_id' => $from_reference_id,
                        'Order_orderhistory.status !=' => 0
                    ]
                );
    
                if ($success) {
                                        
                    // Update KDS tracks for moved KOT item
                    $this->Kds_track->updateAll(
                        array(
                            'Kds_track.order_reference_id' => "'$to_reference_id'",
                            'Kds_track.table_no' => "'".$totable['Order_table']['number']."'",
                            'Kds_track.sync' => 0,
                            'Kds_track.local_sync' => 0
                        ),
                        array(
                            'Kds_track.order_history_id' => (int)$order_id,
                            'Kds_track.order_reference_id' => $from_reference_id
                        )
                    );
                    // Update modifier reference
                    $this->Order_modifier->updateAll(
                        array(
                            'Order_modifier.reference_id' => "'$to_reference_id'",
                            'Order_modifier.sync' => 0,
                            'Order_modifier.local_sync' => 0
                        ),
                        array(
                            'Order_modifier.orderhistory_id' => (int)$order_id,
                            'Order_modifier.reference_id' => $from_reference_id
                        )
                    );


                    $movedCount++;
                }
            }
    
            if ($movedCount > 0) {
                $dataSource->commit();
                $response = ['status' => true, 'message' => "$movedCount item(s) moved successfully"];
            } else {
                $dataSource->rollback();
                $response = ['status' => false, 'message' => 'No items were moved'];
            }
    
        } catch (Exception $e) {
            $dataSource->rollback();
            $response = ['status' => false, 'message' => 'Error: ' . $e->getMessage()];
        }
    
        return json_encode($response);
    }

    
	public function dsr_report_print()
	{
		$cashier_id = $_REQUEST['id']; 
		$startdate = $_REQUEST['sdate'];
		$enddate = $_REQUEST['edate'];
		
		$response = array();
		
		if($cashier_id==''){
			$response =array('status'=> false,'message'=> "Cashier Id Missing");
			return json_encode($response);
		}
		if($startdate==''){
			$response =array('status'=> false,'message'=> "Start date Missing");
			return json_encode($response);
		}
		if($enddate==''){
			$response =array('status'=> false,'message'=> "End date Missing");
			return json_encode($response);
		}
		
		$users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashier_id,'User.status'=>1)));
		if(empty($users)){
			$response =array('status'=> false,'message'=> "User not found");
			return json_encode($response);
		}
		
		$cashiernames=$this->User->find('first',array('conditions'=>array('User.id'=>$cashier_id)));
		$cashiername=$cashiernames['User']['name'];
		$location_id=$cashiernames['User']['location_id'];
		
		$startDatetime = $startdate . ' ' . shiftstart;
		$endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

		// ── Payment Data ──────────────────────────────────────────────
		$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=6,amount,0)) AS upi,
				SUM(IF(type=2,amount,0)) AS card,
				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'
			  AND store_id = $location_id
		");

		$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'
			  AND store_id = $location_id
			GROUP BY type_value
		");

		// ── Transactions ──────────────────────────────────────────────
		$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'
			  AND store_id = $location_id AND status=2
			  AND reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE type=7 AND status=2 AND store_id=$location_id
			  )
		");

		$transactionsnc = $this->Order_transaction->query("
			SELECT SUM(total_tax) AS total_tax
			FROM order_transactions
			WHERE created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND store_id=$location_id AND status=2
			  AND reference_id IN (
				  SELECT reference_id FROM order_payments
				  WHERE type=7 AND status=2 AND store_id=$location_id
			  )
		");

		$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 AND store_id=$location_id
		");

		// ── Taxes ─────────────────────────────────────────────────────
		$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 store_id=$location_id AND status!=0
				  AND reference_id NOT IN (
					  SELECT reference_id FROM order_payments
					  WHERE type=7 AND status=2 AND store_id=$location_id
				  )
			  )
			GROUP BY tax_id
		");

		// ── Net Sale ──────────────────────────────────────────────────
		$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.store_id=$location_id AND ot.status=2
			  AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND ot.reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		// ── NC Net Sale ───────────────────────────────────────────────
		$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.store_id=$location_id AND ot.status=2
			  AND ot.created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND ot.reference_id IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		// ── Taxable / Non-Taxable (normal) ────────────────────────────
		$taxable = $this->Order_orderhistory->query("
			SELECT SUM(total_price) as total_taxable
			FROM order_orderhistories
			WHERE status=2 AND store_id=$location_id
			  AND created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND total_tax_percentage != 0
			  AND reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		$nontaxable = $this->Order_orderhistory->query("
			SELECT SUM(total_price) as total_nontaxable
			FROM order_orderhistories
			WHERE status=2 AND store_id=$location_id
			  AND created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND total_tax_percentage = 0
			  AND reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		// ── NC Taxable / Non-Taxable ──────────────────────────────────
		$nctaxable = $this->Order_orderhistory->query("
			SELECT SUM(total_price) as total_taxable
			FROM order_orderhistories
			WHERE status=2 AND store_id=$location_id
			  AND created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND total_tax_percentage != 0
			  AND reference_id IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		$ncnontaxable = $this->Order_orderhistory->query("
			SELECT SUM(total_price) as total_nontaxable
			FROM order_orderhistories
			WHERE status=2 AND store_id=$location_id
			  AND created BETWEEN '$startDatetime' AND '$endDatetime'
			  AND total_tax_percentage = 0
			  AND reference_id IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
		");

		// ── Sales Aggregation (normal & NC) ───────────────────────────
		$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 store_id=$location_id
						  AND reference_id NOT IN (
							  SELECT reference_id FROM order_payments
							  WHERE type=7 AND status=2 AND store_id=$location_id
						  )
					  )
					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 store_id=$location_id
						  AND reference_id IN (
							  SELECT reference_id FROM order_payments
							  WHERE type=7 AND status=2 AND store_id=$location_id
						  )
					  )
					GROUP BY kds, tax_id
				) as sub
				GROUP BY kds, tax_value
			) as final
			GROUP BY kds, tax_percentage
		");

		// ── Dish Type Sales ───────────────────────────────────────────
		$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.store_id=$location_id AND ooh.status=2
			  AND ooh.reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE store_id=$location_id AND type=7 AND status=2
			  )
			GROUP BY cp.dish_type
			ORDER BY cp.dish_type DESC
		");

		// ── SC Base Sales (for Service Charge Breakup) ────────────────
		$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.store_id=$location_id AND ooh.status=2
			  AND ooh.reference_id NOT IN (
				  SELECT reference_id FROM order_payments
				  WHERE type=7 AND status=2 AND store_id=$location_id
			  )
			GROUP BY cp.dish_type
		");

		// ── Service Charge Breakup Calculation (mirrors view logic) ───
		$sc_sagg5 = 0; $sc_sagg189 = 0;
		foreach ($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 ($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_gst   = round($sc_sagg5   - $sc_bfv, 2);
		$sc_vat   = round($sc_sagg189 - $sc_blq, 2);
		$sc_total = round($sc_gst + $sc_vat, 2);
		$sgst_sc  = round($sc_gst * 0.025, 2);
		$cgst_sc  = round($sc_gst * 0.025, 2);
		$vat_sc   = round($sc_vat * 0.189, 2);

		// ── Dish Type Map ─────────────────────────────────────────────
		$dishTypeMap = [0=>'Food', 1=>'Beverage', 2=>'Liquor', 3=>'Others'];

		// ══════════════════════════════════════════════════════════════
		// BUILD $newData  — mirrors the view left-column + right-column
		// ══════════════════════════════════════════════════════════════
		$newData = [];

		// ── Payment Data ──────────────────────────────────────────────
		$newData[] = ['key'=>'Payment Data',     'value'=>'------', 'heading'=>true];
		$newData[] = ['key'=>'Cashier',            'value'=>$cashiername, 'heading'=>false];
		$newData[] = ['key'=>'Total Collection', 'value'=>(string)round($payments[0][0]['total_amount']-$payments[0][0]['no_charge_with_tax'],2), 'heading'=>false];
		$newData[] = ['key'=>'Cash',             'value'=>(string)round($payments[0][0]['cash'],2),    'heading'=>false];
		$newData[] = ['key'=>'Card',             'value'=>(string)round($payments[0][0]['card'],2),    'heading'=>false];
		$newData[] = ['key'=>'UPI',              'value'=>(string)round($payments[0][0]['upi'],2),     'heading'=>false];
		$newData[] = ['key'=>'Online',           'value'=>(string)round($payments[0][0]['online'],2),  'heading'=>false];

		foreach ($onlinepayments as $op) {
			$newData[] = ['key'=>$op['order_payments']['type_value'], 'value'=>(string)round($op[0]['total_amount'],2), 'heading'=>false];
		}

		$newData[] = ['key'=>'Storecard',           'value'=>(string)round($payments[0][0]['storecard'],2), 'heading'=>false];
		$newData[] = ['key'=>'HoldBill',            'value'=>(string)round($payments[0][0]['hold'],2),      'heading'=>false];
		$newData[] = ['key'=>'No Charge',           'value'=>(string)round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'],2), 'heading'=>false];
		$newData[] = ['key'=>'No Charge With Tax',  'value'=>(string)round($payments[0][0]['no_charge_with_tax'],2), 'heading'=>false];

		// ── Taxes ─────────────────────────────────────────────────────
		$newData[] = ['key'=>'Taxes', 'value'=>'------', 'heading'=>true];
		foreach ($taxes as $tax) {
			$newData[] = [
				'key'     => $tax['order_tax']['tax_name'].'('.$tax['order_tax']['tax_percentage'].'%)',
				'value'   => (string)round($tax[0]['tax_value'],2),
				'heading' => false
			];
		}
		
		$otherChargesTax = round($transactions[0][0]['other_taxes'], 2); 
		if (!empty($otherChargesTax) && $otherChargesTax > 0) {
			$newData[] = [
				'key'     => 'Other Charges Tax',
				'value'   => (string)$otherChargesTax,
				'heading' => false
			];
		}

		// ── Sales Aggregation ─────────────────────────────────────────
		$newData[] = ['key'=>'Sales Aggregation', 'value'=>'------', 'heading'=>true];
		foreach ($sales as $sale) {
			$newData[] = [
				'key'     => $sale['final']['kds_name'].' ('.$sale['final']['tax_percentage'].'%)',
				'value'   => (string)round($sale['final']['value'],2),
				'heading' => false
			];
		}

		// ── NC Sales Aggregation ──────────────────────────────────────
		$newData[] = ['key'=>'NC Sales Aggregation', 'value'=>'------', 'heading'=>true];
		foreach ($ncsales as $ncsale) {
			$newData[] = [
				'key'     => $ncsale['final']['kds_name'].' ('.$ncsale['final']['tax_percentage'].'%)',
				'value'   => (string)round($ncsale['final']['value'],2),
				'heading' => false
			];
		}

		// ── Dish Type Sales ───────────────────────────────────────────
		$newData[] = ['key'=>'Dish Type Sales', 'value'=>'------', 'heading'=>true];
		foreach ($dish_sales as $row) {
			$newData[] = [
				'key'     => $dishTypeMap[(int)$row['cp']['dish_type']] ?? $row['cp']['dish_type'],
				'value'   => (string)round($row[0]['total_amount'] ?? 0, 2),
				'heading' => false
			];
		}

		// ── Service Charge Breakup ────────────────────────────────────
		$newData[] = ['key'=>'Service Charge Breakup',     'value'=>'------',         'heading'=>true];
		$newData[] = ['key'=>'Total Service Charge',       'value'=>(string)$sc_total,'heading'=>false];
		$newData[] = ['key'=>'SC on GST Items (5%)',       'value'=>(string)$sc_gst,  'heading'=>false];
		$newData[] = ['key'=>'SC on VAT Items (18.9%)',    'value'=>(string)$sc_vat,  'heading'=>false];
		$newData[] = ['key'=>'SGST on SC (2.5%)',          'value'=>(string)$sgst_sc, 'heading'=>false];
		$newData[] = ['key'=>'CGST on SC (2.5%)',          'value'=>(string)$cgst_sc, 'heading'=>false];
		$newData[] = ['key'=>'VAT on SC (18.9%)',          'value'=>(string)$vat_sc,  'heading'=>false];

		// ── Total Data ────────────────────────────────────────────────
		$newData[] = ['key'=>'Total Data', 'value'=>'------', 'heading'=>true];
		$newData[] = ['key'=>'Subtotal',              'value'=>(string)round($transactionsubtotal[0][0]['price'],2),   'heading'=>false];
		$newData[] = ['key'=>'Discount',              'value'=>(string)round($transactionsubtotal[0][0]['discount'],2),'heading'=>false];
		$newData[] = ['key'=>'Taxable Amount',        'value'=>(string)round($taxable[0][0]['total_taxable']-$transactionsubtotal[0][0]['discount'],2), 'heading'=>false];
		$newData[] = ['key'=>'Non Taxable Amount',    'value'=>(string)round($nontaxable[0][0]['total_nontaxable'],2), 'heading'=>false];
		$newData[] = ['key'=>'NC Taxable Amount',     'value'=>(string)round($nctaxable[0][0]['total_taxable'],2),     'heading'=>false];
		$newData[] = ['key'=>'NC Non Taxable Amount', 'value'=>(string)round($ncnontaxable[0][0]['total_nontaxable'],2),'heading'=>false];
		$newData[] = ['key'=>'NC Net Sale',           'value'=>(string)round($ncnet_amount_query[0][0]['net_amount'],2),'heading'=>false];
		$newData[] = ['key'=>'NC Total Tax',          'value'=>(string)round($transactionsnc[0][0]['total_tax'],2),    'heading'=>false];
		$newData[] = ['key'=>'No Charge',             'value'=>(string)round($payments[0][0]['no_charge_with_tax']-$transactionsnc[0][0]['total_tax'],2), 'heading'=>false];
		$newData[] = ['key'=>'No Charge With Tax',    'value'=>(string)round($payments[0][0]['no_charge_with_tax'],2), 'heading'=>false];
		$newData[] = ['key'=>'Service Charge',        'value'=>(string)round($transactions[0][0]['servicecharge'],2),  'heading'=>false];
		$newData[] = ['key'=>'Delivery Charge',       'value'=>(string)round($transactions[0][0]['delivery_charge'],2),'heading'=>false];
		$newData[] = ['key'=>'Packing Charge',        'value'=>(string)round($transactions[0][0]['packing_charge'],2), 'heading'=>false];
		$newData[] = ['key'=>'Net Sale',              'value'=>(string)round($net_amount_query[0][0]['net_amount'],2),  'heading'=>false];
		$newData[] = ['key'=>'Total Tax',             'value'=>(string)round($transactions[0][0]['total_tax'],2),       'heading'=>false];
		$newData[] = ['key'=>'Final Amount',          'value'=>(string)round($transactions[0][0]['amount'],2),          'heading'=>false];
		$newData[] = ['key'=>'Round',                 'value'=>(string)round($transactions[0][0]['round'],2),           'heading'=>false];
		$newData[] = ['key'=>'Bill Count',            'value'=>(string)round($transactions[0][0]['total_count'],2),     'heading'=>false];
		$newData[] = ['key'=>'Total PAX',             'value'=>(string)round($transactions[0][0]['pax'],2),             'heading'=>false];

		$response = array('status'=>true, 'message'=>"success", 'data'=>$newData);
		return json_encode($response, JSON_PRETTY_PRINT);
	}



    public function kot_print_data()
    {
        $cashierid = $_REQUEST['id'];
        $group_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($group_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Group Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $get_ref_id = $this->Order_orderhistory->query("SELECT reference_id FROM `order_orderhistories` WHERE group_id='$group_id' and status!=0 limit 1");
        $reference_id=$get_ref_id['0']['order_orderhistories']['reference_id'];
        
        $orderitems=[];
        $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and group_id='$group_id' and status!=0");
        if(!empty($orderss))
        {
            
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                foreach($orders_modifiers as $orders_modifier){
                    
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                        );
                    
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->query(
            "SELECT GROUP_CONCAT(id) as id,reference_id,GROUP_CONCAT(orderno) as orderno,device_id,cashier_id,table_number,
            SUM(price) as price,SUM(total_tax) as total_tax,SUM(servicecharge) as servicecharge,SUM(discount) as discount,
            SUM(discount_type_value) as discount_type_value,SUM(delivery_charge) as delivery_charge,SUM(packing_charge) as packing_charge,
            SUM(amount) as amount,SUM(round) as round,discount_type ,name,phone,address,GROUP_CONCAT(remarks) as remarks,status,GROUP_CONCAT(tokenno) as tokenno,
            createtime,created,pax FROM `order_transactions` WHERE reference_id='$reference_id' and status!=0");
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                
                if(!$orders[0]['remarks']){
                    $orders[0]['remarks']='';
                }
                $finalamount=$orders[0]['amount'];
                $cashierid=$orders[0]['cashier_id'];
                $reference_id=$orders['order_transactions']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                // print_r("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status=2 and discount_percentage!=0 limit 1");exit;
                // 🔹 Get KOT numbers
                $kotQuery = $this->Order_orderhistory->query("
                    SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                    FROM order_orderhistories 
                    WHERE reference_id = '$reference_id' and status!=0
                ");
        
                $kot_numbers = '';
                if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                    $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                }
                
                $transactionitems[]=array(
                    'id' => $orders[0]['id'],
                    'reference_id' =>  $orders['order_transactions']['reference_id'],
                    'orderno' =>  $orders[0]['orderno'],
                    'device_id' =>  $orders['order_transactions']['device_id'],
                    'cashier_id' =>  $orders['order_transactions']['cashier_id'],
                    'cashier_name' => isset($users['User']['username']) ? $users['User']['username'] : '',
                    'table_number' =>  $orders['order_transactions']['table_number'],
                    'price' =>  number_format($orders[0]['price'],2),
                    'total_tax' =>  number_format($orders[0]['total_tax'],2),
                    'servicecharge' =>  $orders[0]['servicecharge'],
                    'discount' =>  $orders[0]['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['order_transactions']['discount_type'],
                    'discount_type_value' =>  $orders[0]['discount_type_value'],
                    'delivery_charge' =>  $orders[0]['delivery_charge'],
                    'packing_charge' =>  $orders[0]['packing_charge'],
                    'amount' =>  $orders[0]['amount'],
                    'round' =>  $orders[0]['round'],
                    'name' =>  $orders['order_transactions']['name'],
                    'phone' =>  $orders['order_transactions']['phone'],
                    'address' =>  $orders['order_transactions']['address'],
                    'remarks' =>  $orders['order_transactions']['remarks'],
                    'status' =>  $orders['order_transactions']['status'],
                    'tokenno' =>  $orders[0]['tokenno'],
                    'createtime' =>  $orders['order_transactions']['createtime'],
                    'pax' =>  $orders['order_transactions']['pax'],
                    'created' =>  $orders['order_transactions']['created'],
                    'kot_number' => $kot_numbers
                );
            }
        }
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status=2");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $brandsale=[];
        $brandsaless = $this->Order_transaction->query("SELECT store_id,(SELECT name from locations WHERE id=order_transactions.store_id) as brandname,(SELECT print_line4 from locations WHERE id=order_transactions.store_id) as brandgst,orderno,(SELECT GROUP_CONCAT(CONCAT(type_value, ' - ', amount)) from order_payments WHERE status=2 and reference_id=order_transactions.reference_id and store_id=order_transactions.store_id) as payment_mode FROM `order_transactions` WHERE reference_id='$reference_id' and status!=0 GROUP by store_id");
        if(!empty($brandsaless))
        {
            foreach($brandsaless as $brandsales){
                // print_r($brandsales);exit;
                
                $brandsale[]=array(
                   'store_id'     => $brandsales['order_transactions']['store_id'] ?? '',
                'brandname'    => $brandsales[0]['brandname'] ?? '',
                'brandgst'     => $brandsales[0]['brandgst'] ?? '',
                'orderno'      => $brandsales['order_transactions']['orderno'] ?? '',
                'payment_mode' => $brandsales[0]['payment_mode'] ?? ''
                );
            }
        }
        
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'brandsale'=>$brandsale,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function data_report()
    {
        $cashierid = isset($_REQUEST['id']) ? $_REQUEST['id'] : '';
    
        if ($cashierid == '') {
            return json_encode([
                'status' => false,
                'message' => "Cashier ID Missing",
            ]);
        }
    
        // ✅ Check if cashier exists
        $users = $this->User->find('first', [
            'conditions' => [
                'User.id' => $cashierid,
                'User.status' => 1
            ]
        ]);
    
        if (empty($users)) {
            return json_encode([
                'status' => false,
                'message' => "Cashier not found",
            ]);
        }
    
        // ✅ Date range: last 7 days
        $todayDate = date("Y-m-d");
        $today = new DateTime();
        $today->modify('-7 days');
        $prevdate = $today->format('Y-m-d');
    
        $shiftstart = shiftstart;
        $shiftend = shiftend;
    
        // ✅ Generate all dates in range
        $dateRange = [];
        $currentDate = new DateTime($prevdate);
        $endDate = new DateTime($todayDate);
        while ($currentDate <= $endDate) {
            $dateRange[] = $currentDate->format('Y-m-d');
            $currentDate->modify('+1 day');
        }
    
        // ✅ Initialize default array
        $transactionitems = [];
        foreach ($dateRange as $date) {
            $transactionitems[$date] = [
                'total_amount' => 0,
                'total_tax' => 0,
                'servicecharge' => 0,
                'discount' => 0,
                'delivery_charge' => 0,
                'packing_charge' => 0,
                'round' => 0,
                'cash' => 0,
                'card' => 0,
                'upi' => 0,
                'online' => 0,
                'storecard' => 0,
                'hold' => 0,
                'no_charge' => 0,
                'no_charge_with_tax' => 0,
                'transaction_date' => $date
            ];
        }
    
        // ✅ Main query combining payments + transactions per date
        $transactions = $this->Order_transaction->query("
            SELECT 
                t.txn_date,
                t.total_amount,
                t.total_tax,
                t.servicecharge,
                t.discount,
                t.delivery_charge,
                t.packing_charge,
                t.round,
                p.cash,
                p.card,
                p.upi,
                p.online,
                p.storecard,
                p.hold,
                p.no_charge,
                p.no_charge_with_tax
            FROM (
                SELECT 
                    DATE(created) AS txn_date,
                    SUM(amount) AS total_amount,
                    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(round) AS round
                FROM order_transactions
                WHERE 
                    created BETWEEN '$prevdate $shiftstart' AND '$todayDate $shiftend'
                    AND cashier_id = $cashierid
                    AND status = 2
                    AND reference_id NOT IN (
                        SELECT reference_id 
                        FROM order_payments 
                        WHERE type = 7 AND status = 2 AND cashier_id = $cashierid
                    )
                GROUP BY DATE(created)
            ) t
            LEFT JOIN (
                SELECT 
                    DATE(created) AS paydate,
                    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 upi,
                    SUM(IF(type=9, amount, 0)) AS online,
                    SUM(IF(type=8, amount, 0)) AS storecard,
                    SUM(IF(type=10, amount, 0)) AS hold,
                    SUM(IF(type=7, amount, 0)) AS no_charge_with_tax,
                    SUM(
                        IF(type=7, 
                            ROUND(amount - (
                                SELECT IFNULL(SUM(total_tax),0)
                                FROM order_transactions 
                                WHERE reference_id = order_payments.reference_id
                            ), 2), 
                        0)
                    ) AS no_charge
                FROM order_payments
                WHERE 
                    created BETWEEN '$prevdate $shiftstart' AND '$todayDate $shiftend'
                    AND cashier_id = $cashierid
                    AND status = 2
                GROUP BY DATE(created)
            ) p ON t.txn_date = p.paydate
        ");
    
        // ✅ Merge results
        if (!empty($transactions)) {
            foreach ($transactions as $transaction) {
                $txn_date = $transaction['t']['txn_date'];
                if (isset($transactionitems[$txn_date])) {
                    $transactionitems[$txn_date] = [
                        'total_amount'        => number_format($transaction['t']['total_amount'], 2, '.', ''),
                        'total_tax'           => number_format($transaction['t']['total_tax'], 2, '.', ''),
                        'servicecharge'       => number_format($transaction['t']['servicecharge'], 2, '.', ''),
                        'discount'            => number_format($transaction['t']['discount'], 2, '.', ''),
                        'delivery_charge'     => number_format($transaction['t']['delivery_charge'], 2, '.', ''),
                        'packing_charge'      => number_format($transaction['t']['packing_charge'], 2, '.', ''),
                        'round'               => number_format($transaction['t']['round'], 2, '.', ''),
                        'cash'                => number_format($transaction['p']['cash'], 2, '.', ''),
                        'card'                => number_format($transaction['p']['card'], 2, '.', ''),
                        'upi'                 => number_format($transaction['p']['upi'], 2, '.', ''),
                        'online'              => number_format($transaction['p']['online'], 2, '.', ''),
                        'storecard'           => number_format($transaction['p']['storecard'], 2, '.', ''),
                        'hold'                => number_format($transaction['p']['hold'], 2, '.', ''),
                        'no_charge'           => number_format($transaction['p']['no_charge'], 2, '.', ''),
                        'no_charge_with_tax'  => number_format($transaction['p']['no_charge_with_tax'], 2, '.', ''),
                        'transaction_date'    => $txn_date
                    ];
                }
            }
        }
    
        $transactionitems = array_values($transactionitems);
    
        return json_encode([
            'status' => true,
            'message' => "success",
            'transactions' => $transactionitems
        ]);
    }
    
    public function data_report_export()
    {
        $cashierid = $_REQUEST['id'] ?? '';
        $sdate = $_REQUEST['sdate'] ?? '';
        $edate = $_REQUEST['edate'] ?? '';
        
        $response = [];
    
        if ($cashierid == '' || $sdate == '' || $edate == '') {
            return json_encode([
                'status' => false,
                'message' => 'Missing required parameters (id, sdate, edate)',
            ]);
        }
    
        // Define shift time constants (replace with your actual constants if defined)
        $shiftstart = shiftstart;
        $shiftend   = shiftend;
        
        $startDatetime = $sdate . ' ' . $shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($edate . ' +1 day')) . ' ' . $shiftend;

        // ---- PAYMENTS QUERY ----
        $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=6,amount,0)) AS upi,
                SUM(IF(type=2,amount,0)) AS card,
                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 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'
                AND cashier_id = $cashierid
        ");
    
        // ---- TRANSACTIONS QUERY ----
        $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 total_amount,
                SUM(price) AS total_price,
                SUM(round) AS round
            FROM order_transactions
            WHERE 
                created BETWEEN '$startDatetime' AND '$endDatetime'
                AND cashier_id = $cashierid
                AND status = 2
                AND reference_id NOT IN (
                    SELECT reference_id 
                    FROM order_payments 
                    WHERE type=7 AND status=2 AND cashier_id = $cashierid
                )
        ");
    
        // ---- FORMAT DATA ----
        $p = $payments[0][0];
        $t = $transactions[0][0];
    
        $data = [
            'total_amount'        => number_format($t['total_amount'] ?? 0, 2, '.', ''),
            'total_price'         => number_format($t['total_price'] ?? 0, 2, '.', ''),
            'total_tax'           => number_format($t['total_tax'] ?? 0, 2, '.', ''),
            'servicecharge'       => number_format($t['servicecharge'] ?? 0, 2, '.', ''),
            'discount'            => number_format($t['discount'] ?? 0, 2, '.', ''),
            'delivery_charge'     => number_format($t['delivery_charge'] ?? 0, 2, '.', ''),
            'packing_charge'      => number_format($t['packing_charge'] ?? 0, 2, '.', ''),
            'round'               => number_format($t['round'] ?? 0, 2, '.', ''),
            'cash'                => number_format($p['cash'] ?? 0, 2, '.', ''),
            'card'                => number_format($p['card'] ?? 0, 2, '.', ''),
            'upi'                 => number_format($p['upi'] ?? 0, 2, '.', ''),
            'online'              => number_format($p['online'] ?? 0, 2, '.', ''),
            'storecard'           => number_format($p['storecard'] ?? 0, 2, '.', ''),
            'hold'                => number_format($p['hold'] ?? 0, 2, '.', ''),
            'no_charge'           => number_format($p['no_charge'] ?? 0, 2, '.', ''),
            'no_charge_with_tax'  => number_format($p['no_charge_with_tax'] ?? 0, 2, '.', ''),
            'transaction_count'   => $t['total_count'] ?? 0,
            'from_date'           => $sdate,
            'to_date'             => $edate,
        ];
    
        // ---- EXPORT CSV ----
        $folderPath = WWW_ROOT . 'uploads/reports/';
        if (!file_exists($folderPath)) {
            mkdir($folderPath, 0777, true);
        }
    
        $filename = 'report_' . $cashierid . '_' . time() . '.csv';
        $filePath = $folderPath . $filename;
        $fileUrl = FULL_BASE_URL . $this->webroot . 'uploads/reports/' . $filename;
    
        $fp = fopen($filePath, 'w');
    
        // Add CSV headers
        fputcsv($fp, array_keys($data));
    
        // Add data row
        fputcsv($fp, array_values($data));
    
        fclose($fp);
    
        // ---- RESPONSE ----
        return json_encode([
            'status' => true,
            'message' => 'success',
            'export' => $fileUrl,
            'data' => $data
        ]);
    }

    public function logout()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $id = $_REQUEST['id'];
        if($id==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$id,'User.status'=>1,'User.role'=>'cashier')));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "Cashier not found",
            );
            return json_encode($response);
        }
        
        $tbleschk = $this->Order_table->find('count', [
            'conditions' => [
                'Order_table.status >' => 1
            ],
            'recursive' => -1
        ]);
        
        if ($tbleschk > 0) {
            $response = [
                'status'  => false,
                'message' => "Vacant All Tables first"
            ];
            // return json_encode($response);
        }

        $datas['User_track']=array(
            'user_id'=>$id,
            'location_id'=>$users['User']['location_id'],
            'location_name'=>$users['User']['location_name'],
            'type'=>'logout',
            'remarks'=>'logout'
        );
        if($this->User_track->saveAll($datas['User_track']))
        {
            $response['status']= true;
            $response['message']= "Logged Out..!";
        }else{
            $response['status']= false;
            $response['message']= "Track not Saved..!";
        }
        return json_encode($response);
    }
    /*
    public function split_bill_table_package()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        
        if (!isset($_REQUEST['data'])) {
            $response = array(
                'status' => false,
                'message' => "data not found",
            );
            return json_encode($response);
        }
        
        $data = json_decode($_REQUEST['data'], true);
        
        // Check if JSON is valid
        if ($data === null) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json'
            ]);
        }
        
        // Validate required structure
        if (
            !isset($data['splits']) ||
            !is_array($data['splits']) ||
            count($data['splits']) == 0
        ) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json structure: splits missing'
            ]);
        }
        
        foreach ($data['splits'] as $split) {
        
            // Check items key
            if (!isset($split['items']) || !is_array($split['items']) || count($split['items']) == 0) {
                return json_encode([
                    'status' => false,
                    'message' => 'invalid json structure: items missing'
                ]);
            }
        
            foreach ($split['items'] as $item) {
        
                if (
                    !isset($item['id']) ||
                    !isset($item['reference_id']) ||
                    !isset($item['quantity'])
                ) {
                    return json_encode([
                        'status' => false,
                        'message' => 'invalid json structure: item keys missing'
                    ]);
                }
            }
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        
        $orderQtyRes = $this->Order_orderhistory->query("
            SELECT id, SUM(quantity) as total_qty,product_name
            FROM order_orderhistories
            WHERE reference_id = '$table_referenceid'
              AND status != 0
            GROUP BY product_id
        ");
        $originalQty = [];
        
        foreach ($orderQtyRes as $row) {
            $itemId = $row['order_orderhistories']['id'];
            $originalQty[$itemId] = (int)$row[0]['total_qty'];
            $originalname[$itemId] = $row['order_orderhistories']['product_name'];
        }
        
        $splitQty = [];
        
        foreach ($data['splits'] as $split) {
            foreach ($split['items'] as $item) {
        
                $id = $item['id'];
                $qty = (int)$item['quantity'];
        
                if (!isset($splitQty[$id])) {
                    $splitQty[$id] = 0;
                }
        
                $splitQty[$id] += $qty;
            }
        }
        
        foreach ($originalQty as $itemId => $qtyFromOrder) {
        
            $qtyFromSplit = isset($splitQty[$itemId]) ? $splitQty[$itemId] : 0;
        
            if ($qtyFromSplit != $qtyFromOrder) {
                return json_encode([
                    'status' => false,
                    'message' => "Invalid quantity for {$originalName[$itemId]}: Ordered $qtyFromOrder, Given $qtyFromSplit"
                ]);
            }
        }

        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];

        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'              => 0,
                'Order_table.local_sync'        => 0
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
        
        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                
                $round_amount = $finalamount - $roundfinalamount;
                $split_count = count($data['splits']);
                
                $is_split=1;
                if($split_count==1){
                    $split_count=0;
                    $is_split=0;
                }
                
                $this->Order_transaction->begin();
                
                try {
                
                    // =========================================================
                    // 1. SAVE ALL SPLIT DETAILS (orderhistory + tax + split tx)
                    // =========================================================
                    
                    $series_id=sprintf("%02d", $cashierid);
                    $users=$this->User->find('first',array('conditions'=>array('id'=>$cashierid)));
                    $series=strtoupper(substr($users['User']['username'],0,2)); 

                    $ordertrx=$this->Order_transaction->query("SELECT orderno,split_count FROM `order_transactions` order by id desc limit 1");
                    
                    if($ordertrx[0]['order_transactions']['split_count']>1){
                     $last_split_count=$ordertrx[0]['order_transactions']['split_count']-1;
                    }else{
                     $last_split_count=0;
                    }
                     
                    $ordernewstring = substr($ordertrx[0]['order_transactions']['orderno'], -8) + $last_split_count;
                    $ordernonewno=$ordernewstring+1;
                    
                    foreach ($data['splits'] as $block) {
                
                        $refId = null;
                        $blockAmount = 0;   // initialize
                        $blockTax    = 0;   // initialize
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_transaction->find('first', array('fields' => 'Order_transaction.id', 'conditions' => array('Order_transaction.reference_id' => $pin))));
                        
                        foreach ($block['items'] as $item) {
                
                            $orderId = $item['id'];
                            $refId   = $item['reference_id'];
                            $qty     = (int)$item['quantity'];
                
                            // ------------------------------------------
                            // FETCH ORIGINAL ORDERHISTORY
                            // ------------------------------------------
                            $original = $this->Order_orderhistory->find('first', [
                                'conditions' => [
                                    'Order_orderhistory.id' => $orderId,
                                    'Order_orderhistory.reference_id' => $refId,
                                    'Order_orderhistory.status !=' => 0
                                ]
                            ]);
                
                            if (empty($original)) {
                                throw new Exception("Original orderhistory not found: ID $orderId");
                            }
                
                            // prepare new row
                            $new = $original['Order_orderhistory'];
                            
                            $new['order_history_id'] = $new['id'];
                            unset($new['id']);
                            
                            $new['quantity'] = $qty;
                
                            // recalc
                            $new['total_tax']   = (($new['price'] * $qty) * $new['total_tax_percentage']) / 100;
                            $new['total_price'] = ($new['price'] * $qty) + $new['total_tax'];
                            
                            $new['split_reference_id'] = $pin;
                        
                            // SAVE split orderhistory
                            $this->Order_split_orderhistory->create();
                            if (!$this->Order_split_orderhistory->save($new)) {
                                throw new Exception("Failed saving Order_split_orderhistory");
                            }
                
                            // accumulate split totals
                            $blockAmount += $new['price'] * $qty;
                            $blockTax    += $new['total_tax'];
                
                            // ------------------------------------------
                            // FETCH RELATED TAX ROWS
                            // ------------------------------------------
                            $taxRows = $this->Order_tax->find('all', [
                                'conditions' => [
                                    'Order_tax.orderhistory_id' => $orderId,
                                    'Order_tax.reference_id'    => $refId,
                                    'Order_tax.status !='       => 0
                                ]
                            ]);
                
                            // foreach ($taxRows as $row) {
                
                            //     $taxData = $row['Order_tax'];
                
                            //     unset($taxData['id']);
                            //     unset($taxData['created']);
                            //     unset($taxData['modified']);
                
                            //     $taxData['quantity']       = $qty;
                            //     $taxData['taxable_price']  = $taxData['price'] * $qty;
                            //     $taxData['tax_value']      = ($taxData['taxable_price'] * $taxData['tax_percentage']) / 100;
                
                            //     $taxData['orderhistory_id'] = $orderId;
                
                            //     $this->Order_split_tax->create();
                            //     if (!$this->Order_split_tax->save($taxData)) {
                            //         throw new Exception("Failed saving Order_split_tax");
                            //     }
                            // }
                
                        } // end items loop
                
                        // =========================================================
                        // 2. SAVE SPLIT TRANSACTION FOR THIS BLOCK
                        // =========================================================
                
                        $tx = [];
                        $tx['split_reference_id'] = $pin;
                        
                        $tx['reference_id'] = $refId;
                        $tx['store_id']     = $location_id;
                        $tx['device_id']    = $device_id;
                        $tx['cashier_id']   = $cashierid;
                        $tx['waiter_id']    = $waiter_id;
                        $tx['waiter_name']  = $waiter_name;
                        $tx['name']         = $name;
                        $tx['phone']        = $phone;
                        $tx['address']      = $address;
                
                        $tx['price']        = round($blockAmount, 2);
                        $tx['total_tax']    = round($blockTax, 2);
                        $tx['amount']       = round($blockAmount + $blockTax, 2);
                
                        $tx['is_split']     = 1;
                        $tx['createtime']   = $currenttime;
                        
                        $GOrder = sprintf("%08d", $ordernonewno);
                        $orderNumber = $series_id."".$series.date('Y').$GOrder;     
            
                        $tx['orderno']   = $orderNumber;
                        
                        $tx['createtime']   = $currenttime;
                        
                        $this->Order_split_transaction->create();
                        if (!$this->Order_split_transaction->save($tx)) {
                            throw new Exception("Failed saving split transaction");
                        }
                    
                        $ordernonewno++;
                    
                    } // end block loop
                
                    // =========================================================
                    // 3. SAVE MAIN / FINAL ORDER_TRANSACTION
                    // =========================================================
                    $datas['Order_transaction']=array(
                        'reference_id'=>$table_referenceid,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'store_id'=>$location_id,
                        'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                        'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                        'discount'=>round($orderss[0][0]['discount'],2),
                        'amount'=>$finalamount,
                        'round'=>round($round_amount,2),
                        'name'=>$name,
                        'phone'=>$phone,
                        'address'=>$address,
                        'tokenno'=>$token,
                        'table_number'=>$table_number,
                        'pax'=>$pax,
                        'waiter_id'=>$waiter_id,
                        'waiter_name'=>$waiter_name,
                        'is_takeaway' => $is_takeaway,
                        'createtime'=>$currenttime,
                        'is_split' => $is_split,
                        'split_count' => $split_count,
                        'split_type' => 'item'
                    );
                
                    if (!$this->Order_transaction->save($datas['Order_transaction'])) {
                        throw new Exception("Failed to save final Order_transaction");
                    }
                
                    // =========================================================
                    // 4. UPDATE TABLES (ONLY IF EVERYTHING ABOVE SUCCESS)
                    // =========================================================
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 3,sync=0,local_sync=0
                        WHERE reference_id = '$table_referenceid' AND status != 0
                    ");
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 1,sync=0,local_sync=0
                        WHERE reference_id IN ($refid) AND status != 0
                    ");
                
                    $this->Order_table_tracking->query("
                        UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0
                        WHERE merged_table_ref_id IN ($refid)
                    ");
                
                    // COMMIT ALL
                    $this->Order_transaction->commit();
                
                    return json_encode([
                        'status' => true,
                        'message' => 'Split saved and final transaction saved successfully'
                    ]);
                
                } catch (Exception $e) {
                
                    $this->Order_transaction->rollback();
                
                    return json_encode([
                        'status' => false,
                        'message' => $e->getMessage()
                    ]);
                }
                
            }
        
        return json_encode($response);
    }
    */
    
    public function split_bill_table_package()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        
        if (!isset($_REQUEST['data'])) {
            $response = array(
                'status' => false,
                'message' => "data not found",
            );
            return json_encode($response);
        }
        
        $data = json_decode($_REQUEST['data'], true);
        
        // Check if JSON is valid
        if ($data === null) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json'
            ]);
        }
        
        // Validate required structure
        if (
            !isset($data['splits']) ||
            !is_array($data['splits']) ||
            count($data['splits']) == 0
        ) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json structure: splits missing'
            ]);
        }
        
        foreach ($data['splits'] as $split) {
        
            // Check items key
            if (!isset($split['items']) || !is_array($split['items']) || count($split['items']) == 0) {
                return json_encode([
                    'status' => false,
                    'message' => 'invalid json structure: items missing'
                ]);
            }
        
            foreach ($split['items'] as $item) {
        
                if (
                    !isset($item['id']) ||
                    !isset($item['reference_id']) ||
                    !isset($item['quantity'])
                ) {
                    return json_encode([
                        'status' => false,
                        'message' => 'invalid json structure: item keys missing'
                    ]);
                }
            }
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        
        $orderQtyRes = $this->Order_orderhistory->query("
            SELECT id, quantity, product_name, product_id
            FROM order_orderhistories
            WHERE reference_id = '$table_referenceid'
              AND status != 0
        ");
        
        $originalQty  = [];   // order_history_id -> qty
        $originalName = [];   // order_history_id -> product_name

        // Maps for product_id-keyed payloads (POS format)
        $productQty       = [];   // product_id -> total available qty
        $productName      = [];   // product_id -> product_name
        $productHistories = [];   // product_id -> [order_history_ids, ...]

        foreach ($orderQtyRes as $row) {
            
            $hid  = $row['order_orderhistories']['id'];
            $pid  = $row['order_orderhistories']['product_id'];
            $qty  = (int)$row['order_orderhistories']['quantity'];
            $name = $row['order_orderhistories']['product_name'];

            $originalQty[$hid]  = $qty;
            $originalName[$hid] = $name;

            if (!isset($productQty[$pid])) {
                $productQty[$pid]       = 0;
                $productName[$pid]      = $name;
                $productHistories[$pid] = [];
            }
            $productQty[$pid] += $qty;
            $productHistories[$pid][] = $hid;

        }
        
        // $splitQty = [];
        
        // foreach ($data['splits'] as $split) {
        //     foreach ($split['items'] as $item) {
        
        //         $id = $item['id'];
        //         $qty = (int)$item['quantity'];
        
        //         if (!isset($splitQty[$id])) {
        //             $splitQty[$id] = 0;
        //         }
        
        //         $splitQty[$id] += $qty;
        //     }
        // }
        
        
        // Detect whether the payload uses product_id or order_history_id keys.
        // A key is treated as product_id format when it is NOT a known
        // order_history_id but IS a known product_id for this reference.
        $payloadUsesProductId = false;
        foreach ($data['splits'] as $_chkSplit) {
            foreach ($_chkSplit['items'] as $_chkItem) {
                if (!array_key_exists($_chkItem['id'], $originalQty)
                    && array_key_exists($_chkItem['id'], $productQty)) {
                    $payloadUsesProductId = true;
                    break 2;
                }
            }
        }
        
        unset($_chkSplit, $_chkItem);

        if ($payloadUsesProductId) {
            // ── Product_id mode: validate totals then normalize to history ids ──

            $splitProductQty = [];
            foreach ($data['splits'] as $_sp) {
                foreach ($_sp['items'] as $_it) {
                    $splitProductQty[$_it['id']] =
                        ($splitProductQty[$_it['id']] ?? 0) + (int)$_it['quantity'];
                }
            }
            unset($_sp, $_it);

            foreach ($splitProductQty as $_pid => $_reqQty) {
                $_avail = isset($productQty[$_pid]) ? $productQty[$_pid] : 0;
                if ($_reqQty > $_avail) {
                    $_pname = isset($productName[$_pid]) ? $productName[$_pid] : 'Product #'.$_pid;
                    return json_encode([
                        'status'  => false,
                        'message' => "Invalid quantity for $_pname: Available $_avail, Requested $_reqQty"
                    ]);
                }
            }
            unset($_pid, $_reqQty, $_avail, $_pname);

            // Normalize: replace product_id with order_history_id, distributing
            // quantity across history rows in the order they were returned.
            $_histRemaining = [];
            foreach ($orderQtyRes as $_r) {
                $_histRemaining[$_r['order_orderhistories']['id']] =
                    (int)$_r['order_orderhistories']['quantity'];
            }
            unset($_r);

            $normalizedSplits = [];
            foreach ($data['splits'] as $_split) {
                $_newItems = [];
                foreach ($_split['items'] as $_item) {
                    $_pid    = $_item['id'];
                    $_needed = (int)$_item['quantity'];
                    foreach ($productHistories[$_pid] as $_hid) {
                        if ($_needed <= 0) break;
                        $_canUse = min($_needed, $_histRemaining[$_hid]);
                        if ($_canUse <= 0) continue;
                        $_histRemaining[$_hid] -= $_canUse;
                        $_needed -= $_canUse;
                        $_newItems[] = [
                            'id'           => $_hid,
                            'reference_id' => $_item['reference_id'],
                            'quantity'     => $_canUse,
                        ];
                    }
                }
                $normalizedSplits[] = array_merge($_split, ['items' => $_newItems]);
            }
            unset($_split, $_item, $_pid, $_needed, $_hid, $_canUse, $_histRemaining, $_newItems);

            // Apply normalized splits back so downstream code sees history ids
            $data['splits'] = $normalizedSplits;
            unset($normalizedSplits);

        } else {
            // ── Order_history_id mode: original row-exact validation ──

            $splitQty = [];
            foreach ($data['splits'] as $split) {
                foreach ($split['items'] as $item) {
                    $id  = $item['id'];
                    $qty = (int)$item['quantity'];
                    if (!isset($splitQty[$id])) { $splitQty[$id] = 0; }
                    $splitQty[$id] += $qty;
                }
            }

            foreach ($originalQty as $itemId => $qtyFromOrder) {
                $qtyFromSplit = isset($splitQty[$itemId]) ? $splitQty[$itemId] : 0;
                if ($qtyFromSplit != $qtyFromOrder) {
                    $itemName = isset($originalName[$itemId]) ? $originalName[$itemId] : 'Item #'.$itemId;
                    return json_encode([
                        'status'  => false,
                        'message' => "Invalid quantity for $itemName: Ordered $qtyFromOrder, Given $qtyFromSplit"
                    ]);
                }
            }
        }

                    
        // foreach ($originalQty as $itemId => $qtyFromOrder) {
        
        //     $qtyFromSplit = isset($splitQty[$itemId]) ? $splitQty[$itemId] : 0;
        
        //     if ($qtyFromSplit != $qtyFromOrder) {
        //         return json_encode([
        //             'status' => false,
        //             'message' => "Invalid quantity for {$originalName[$itemId]}: Ordered $qtyFromOrder, Given $qtyFromSplit"
        //         ]);
        //     }
        // }
        
        // Preserve the validated/normalised splits before $data may be
        // overwritten by the customer-save block further below.
        $splitBlocks = $data['splits'];

        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['customer_pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];

        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'              => 0,
                'Order_table.local_sync'        => 0
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
        
        $refid = []; // T9-fix: no merged tables guard

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                
                $round_amount = $finalamount - $roundfinalamount;
                // $split_count = count($data['splits']);
                $split_count = count($splitBlocks);

                $is_split=1;
                if($split_count==1){
                    $split_count=0;
                    $is_split=0;
                }
                
                $this->Order_transaction->begin();
                
                try {
                
                    // =========================================================
                    // 1. SAVE ALL SPLIT DETAILS (orderhistory + tax + split tx)
                    // =========================================================
                    
                    $series_id=sprintf("%02d", $cashierid);
                    $users=$this->User->find('first',array('conditions'=>array('id'=>$cashierid)));
                    $series=strtoupper(substr($users['User']['username'],0,2)); 

                    $ordertrx=$this->Order_transaction->query("SELECT orderno,split_count FROM `order_transactions` order by id desc limit 1");
                    
                    if($ordertrx[0]['order_transactions']['split_count']>1){
                     $last_split_count=$ordertrx[0]['order_transactions']['split_count']-1;
                    }else{
                     $last_split_count=0;
                    }
                     
                    $ordernewstring = substr($ordertrx[0]['order_transactions']['orderno'], -8) + $last_split_count;
                    $ordernonewno=$ordernewstring+1;
                    
                    // foreach ($data['splits'] as $block) {
                    foreach ($splitBlocks as $block) {

                
                        $refId = null;
                        $blockAmount = 0;   // initialize
                        $blockTax    = 0;   // initialize
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_transaction->find('first', array('fields' => 'Order_transaction.id', 'conditions' => array('Order_transaction.reference_id' => $pin))));
                        
                        foreach ($block['items'] as $item) {
                
                            $orderId = $item['id'];
                            $refId   = $item['reference_id'];
                            $qty     = (int)$item['quantity'];
                
                            // ------------------------------------------
                            // FETCH ORIGINAL ORDERHISTORY
                            // ------------------------------------------
                            $original = $this->Order_orderhistory->find('first', [
                                'conditions' => [
                                    'Order_orderhistory.id' => $orderId,
                                    'Order_orderhistory.reference_id' => $refId,
                                    'Order_orderhistory.status !=' => 0
                                ]
                            ]);
                
                            if (empty($original)) {
                                throw new Exception("Original orderhistory not found: ID $orderId");
                            }
                
                            // prepare new row
                            $new = $original['Order_orderhistory'];
                            
                            $new['order_history_id'] = $new['id'];
                            unset($new['id']);
                            
                            $new['quantity'] = $qty;
                
                            // recalc
                            $new['total_tax']   = (($new['price'] * $qty) * $new['total_tax_percentage']) / 100;
                            $new['total_price'] = ($new['price'] * $qty) + $new['total_tax'];
                            
                            $new['split_reference_id'] = $pin;
                        
                            // SAVE split orderhistory
                            $this->Order_split_orderhistory->create();
                            if (!$this->Order_split_orderhistory->save($new)) {
                                throw new Exception("Failed saving Order_split_orderhistory");
                            }
                            
                            // T8-fix: copy modifier rows for this orderhistory item into the split bill.
                            // Modifiers are linked by orderhistory_id+reference_id; we copy them
                            // with the new split_reference_id so the split bill shows correct modifiers.
                            $modifierRows = $this->Order_modifier->find('all', [
                                'conditions' => [
                                    'Order_modifier.orderhistory_id' => $orderId,
                                    'Order_modifier.reference_id'    => $refId,
                                    'Order_modifier.status !='       => 0
                                ]
                            ]);
                            foreach ($modifierRows as $modRow) {
                                $modData = $modRow['Order_modifier'];
                                unset($modData['id'], $modData['created'], $modData['modified']);
                                $modData['reference_id']       = $refId;
                                $modData['split_reference_id'] = $pin;
                                $modData['sync']               = 0;
                                $modData['local_sync']         = 0;
                                $this->Order_modifier->create();
                                if (!$this->Order_modifier->save($modData)) {
                                    throw new Exception("Failed saving split modifier for orderhistory_id=$orderId");
                                }
                            }
                        

                            // accumulate split totals
                            $blockAmount += $new['price'] * $qty;
                            $blockTax    += $new['total_tax'];
                
                            // ------------------------------------------
                            // FETCH RELATED TAX ROWS
                            // ------------------------------------------
                            $taxRows = $this->Order_tax->find('all', [
                                'conditions' => [
                                    'Order_tax.orderhistory_id' => $orderId,
                                    'Order_tax.reference_id'    => $refId,
                                    'Order_tax.status !='       => 0
                                ]
                            ]);
                
                            // foreach ($taxRows as $row) {
                
                            //     $taxData = $row['Order_tax'];
                
                            //     unset($taxData['id']);
                            //     unset($taxData['created']);
                            //     unset($taxData['modified']);
                
                            //     $taxData['quantity']       = $qty;
                            //     $taxData['taxable_price']  = $taxData['price'] * $qty;
                            //     $taxData['tax_value']      = ($taxData['taxable_price'] * $taxData['tax_percentage']) / 100;
                
                            //     $taxData['orderhistory_id'] = $orderId;
                
                            //     $this->Order_split_tax->create();
                            //     if (!$this->Order_split_tax->save($taxData)) {
                            //         throw new Exception("Failed saving Order_split_tax");
                            //     }
                            // }
                
                        } // end items loop
                
                        // =========================================================
                        // 2. SAVE SPLIT TRANSACTION FOR THIS BLOCK
                        // =========================================================
                
                        $tx = [];
                        $tx['split_reference_id'] = $pin;
                        
                        $tx['reference_id'] = $refId;
                        $tx['store_id']     = $location_id;
                        $tx['device_id']    = $device_id;
                        $tx['cashier_id']   = $cashierid;
                        $tx['waiter_id']    = $waiter_id;
                        $tx['waiter_name']  = $waiter_name;
                        $tx['name']         = $name;
                        $tx['phone']        = $phone;
                        $tx['address']      = $address;
                
                        $tx['price']        = round($blockAmount, 2);
                        $tx['total_tax']    = round($blockTax, 2);
                        $tx['amount']       = round($blockAmount + $blockTax, 2);
                
                        $tx['is_split']     = 1;
                        $tx['createtime']   = $currenttime;
                        
                        $GOrder = sprintf("%08d", $ordernonewno);
                        $orderNumber = $series_id."".$series.date('Y').$GOrder;     
            
                        $tx['orderno']   = $orderNumber;
                        
                        $tx['createtime']   = $currenttime;
                        
                        $this->Order_split_transaction->create();
                        if (!$this->Order_split_transaction->save($tx)) {
                            throw new Exception("Failed saving split transaction");
                        }
                    
                        $ordernonewno++;
                    
                    } // end block loop
                
                    // =========================================================
                    // 3. SAVE MAIN / FINAL ORDER_TRANSACTION
                    // =========================================================
                    $datas['Order_transaction']=array(
                        'reference_id'=>$table_referenceid,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'store_id'=>$location_id,
                        'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                        'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                        'discount'=>round($orderss[0][0]['discount'],2),
                        'amount'=>$finalamount,
                        'round'=>round($round_amount,2),
                        'name'=>$name,
                        'phone'=>$phone,
                        'address'=>$address,
                        'tokenno'=>$token,
                        'table_number'=>$table_number,
                        'pax'=>$pax,
                        'waiter_id'=>$waiter_id,
                        'waiter_name'=>$waiter_name,
                        'is_takeaway' => $is_takeaway,
                        'createtime'=>$currenttime,
                        'is_split' => $is_split,
                        'split_count' => $split_count,
                        'split_type' => 'item'
                    );
                
                    if (!$this->Order_transaction->save($datas['Order_transaction'])) {
                        throw new Exception("Failed to save final Order_transaction");
                    }
                
                    // =========================================================
                    // 4. UPDATE TABLES (ONLY IF EVERYTHING ABOVE SUCCESS)
                    // =========================================================
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 3,sync=0,local_sync=0
                        WHERE reference_id = '$table_referenceid' AND status != 0
                    ");
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 1,sync=0,local_sync=0
                        WHERE reference_id IN ($refid) AND status != 0
                    ");
                
                    $this->Order_table_tracking->query("
                        UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0
                        WHERE merged_table_ref_id IN ($refid)
                    ");
                
                    // COMMIT ALL
                    $this->Order_transaction->commit();
                
                    return json_encode([
                        'status' => true,
                        'message' => 'Split saved and final transaction saved successfully'
                    ]);
                
                } catch (Exception $e) {
                
                    $this->Order_transaction->rollback();
                
                    return json_encode([
                        'status' => false,
                        'message' => $e->getMessage()
                    ]);
                }
                
            }
        
        return json_encode($response);
    }
    
    public function split_fetch_unsettled_bill()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
    
        // Validate cashier id
        if ($cashierid == '') {
            return json_encode([
                'status' => false,
                'message' => "Cashier Id Missing"
            ]);
        }
    
        // Validate reference id
        if ($reference_id == '') {
            return json_encode([
                'status' => false,
                'message' => "Reference Id Missing"
            ]);
        }
    
        // Validate user
        $users = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1]
        ]);
    
        if (empty($users)) {
            return json_encode([
                'status' => false,
                'message' => "User not found"
            ]);
        }
    
        $transactionitems = [];
        $finalamount = 0;
    
        $transactions = $this->Order_transaction->find('all', [
            'conditions' => ['reference_id' => $reference_id, 'status !=' => 0]
        ]);
        if (empty($transactions)){
            return json_encode([
                'status' => false,
                'message' => "Transaction Not Found"
            ]);
        }
        
        if($transactions[0]['Order_transaction']['is_split']){
            
            // $splittransactions = $this->Order_split_transaction->find('all', [
            //     'conditions' => ['reference_id' => $reference_id, 'status !=' => 0]
            // ]);
            
            $splittransactions = $this->Order_split_transaction->find('all', [
                'fields' => [
                    'Order_split_transaction.*',
                    'SUM(Order_split_transaction.amount) AS total_amount'
                ],
                'conditions' => [
                    'Order_split_transaction.reference_id' => $reference_id,
                    'Order_split_transaction.status !=' => 0
                ],
                'group' => ['Order_split_transaction.id']
            ]);
            
            if (!empty($splittransactions)) {
        
                # ============================================================
                # ✅ RETURN ONLY SPLIT BILL DATA
                # ============================================================
                $finalamount=0;
                $finalpayment=0;
                
                foreach ($splittransactions as $split) {
                    $finalamount = $split[0]['total_amount'];
                    $split_id=$split['Order_split_transaction']['id'];
                    
                    $allpayments=$this->Order_split_payment->query("SELECT sum(amount) as pay_amount FROM `order_split_payments` WHERE split_txn_id='$split_id' and reference_id='$reference_id' and status!=0");
                    if($allpayments){
                        $finalpayment=$allpayments[0][0]['pay_amount'];
                    }
                    $amount_diff=round(($finalamount-$finalpayment),2);
                    
                    if($amount_diff>0){
                        if (!$split['Order_split_transaction']['remarks']) {
                            $split['Order_split_transaction']['remarks'] = '';
                        }
            
                        $split_reference = $split['Order_split_transaction']['reference_id'];
            
                        # ------------------------------------------------------------
                        # 🔹 FETCH SPLIT DISCOUNT PERCENTAGE
                        # ------------------------------------------------------------
            
                        $split_discount_percentage = "0";
            
                        $splitdiscper = $this->Order_tax->query("
                            SELECT discount_percentage 
                            FROM order_tax 
                            WHERE reference_id = '$split_reference'
                            AND status != 0 
                            AND discount_percentage != 0 
                            LIMIT 1
                        ");
            
                        if (!empty($splitdiscper)) {
                            $split_discount_percentage = number_format($splitdiscper[0]['order_tax']['discount_percentage'], 2);
                        }
            
                        # ------------------------------------------------------------
                        # 🔹 FETCH SPLIT KOT NUMBERS
                        # ------------------------------------------------------------
            
                        $split_kotQuery = $this->Order_split_orderhistory->query("
                            SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                            FROM order_split_orderhistories 
                            WHERE reference_id = '$split_reference'
                            AND status != 0
                        ");
            
                        $split_kot_numbers = '';
                        if (!empty($split_kotQuery) && isset($split_kotQuery[0][0]['kot_numbers'])) {
                            $split_kot_numbers = $split_kotQuery[0][0]['kot_numbers'];
                        }
            
                        # ------------------------------------------------------------
                        # 🔹 ADD SPLIT TRANSACTION TO ARRAY
                        # ------------------------------------------------------------
            
                        $transactionitems[] = [
                            'id'                   => $split['Order_split_transaction']['id'],
                            'reference_id'         => $split['Order_split_transaction']['reference_id'],
                            'split_reference_id'   => $split['Order_split_transaction']['split_reference_id'] ?? '',
                            'orderno'              => $split['Order_split_transaction']['orderno'],
                            'device_id'            => $split['Order_split_transaction']['device_id'],
                            'cashier_id'           => $split['Order_split_transaction']['cashier_id'],
                            'table_number'         => $split['Order_split_transaction']['table_number'],
                            'price'                => $split['Order_split_transaction']['price'],
                            'total_tax'            => $split['Order_split_transaction']['total_tax'],
                            'servicecharge'        => $split['Order_split_transaction']['servicecharge'],
                            'discount'             => $split['Order_split_transaction']['discount'],
                            'discount_percentage'  => $split_discount_percentage,
                            'delivery_charge'      => $split['Order_split_transaction']['delivery_charge'],
                            'packing_charge'       => $split['Order_split_transaction']['packing_charge'],
                            'amount'               => $split['Order_split_transaction']['amount'],
                            'round'                => $split['Order_split_transaction']['round'],
                            'name'                 => $split['Order_split_transaction']['name'],
                            'phone'                => $split['Order_split_transaction']['phone'],
                            'address'              => $split['Order_split_transaction']['address'],
                            'remarks'              => $split['Order_split_transaction']['remarks'],
                            'status'               => $split['Order_split_transaction']['status'],
                            'tokenno'              => $split['Order_split_transaction']['tokenno'],
                            'createtime'           => $split['Order_split_transaction']['createtime'],
                            'created'              => $split['Order_split_transaction']['created'],
                            'pax'                  => $split['Order_split_transaction']['pax'],
                            'kot_number'           => $split_kot_numbers
                        ];
                    }
                }
            
                # RETURN SPLIT RESPONSE
                return json_encode([
                    'status' => true,
                    'is_split_bill' => true,
                    'data' => $transactionitems
                ]);
            }
        }else{
            # ============================================================
            # 🔍 STEP 1: CHECK IF SPLIT TRANSACTIONS EXIST
            # ============================================================
            
            foreach ($transactions as $orders) {
                $finalamount=$orders['Order_transaction']['amount'];
                
                $finalpayment=0;
                $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
                if($allpayments){
                    $finalpayment=$allpayments[0][0]['pay_amount'];
                }
                $amount_diff=round(($finalamount-$finalpayment),2);
                
                if($amount_diff>0){
                    
                    if (!$orders['Order_transaction']['remarks']) {
                        $orders['Order_transaction']['remarks'] = '';
                    }
        
                    $order_ref = $orders['Order_transaction']['reference_id'];
                    
                    # ------------------------------------------------------------
                    # 🔹 DISCOUNT %
                    # ------------------------------------------------------------
        
                    $discount_percentage = "0";
        
                    $discper = $this->Order_tax->query("
                        SELECT discount_percentage 
                        FROM order_tax 
                        WHERE reference_id = '$order_ref'
                        AND status != 0 
                        AND discount_percentage != 0 
                        LIMIT 1
                    ");
        
                    if (!empty($discper)) {
                        $discount_percentage = number_format($discper[0]['order_tax']['discount_percentage'], 2);
                    }
        
                    # ------------------------------------------------------------
                    # 🔹 KOT NUMBERS
                    # ------------------------------------------------------------
        
                    $kotQuery = $this->Order_orderhistory->query("
                        SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                        FROM order_orderhistories 
                        WHERE reference_id = '$order_ref'
                        AND status != 0
                    ");
        
                    $kot_numbers = '';
                    if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                        $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                    }
        
                    # ------------------------------------------------------------
                    # 🔹 ADD NORMAL TRANSACTION
                    # ------------------------------------------------------------
        
                    $transactionitems[] = [
                        'id'                   => $orders['Order_transaction']['id'],
                        'reference_id'         => $orders['Order_transaction']['reference_id'],
                        'split_reference_id'   => '',
                        'orderno'              => $orders['Order_transaction']['orderno'],
                        'device_id'            => $orders['Order_transaction']['device_id'],
                        'cashier_id'           => $orders['Order_transaction']['cashier_id'],
                        'table_number'         => $orders['Order_transaction']['table_number'],
                        'price'                => $orders['Order_transaction']['price'],
                        'total_tax'            => $orders['Order_transaction']['total_tax'],
                        'servicecharge'        => $orders['Order_transaction']['servicecharge'],
                        'discount'             => $orders['Order_transaction']['discount'],
                        'discount_percentage'  => $discount_percentage,
                        'delivery_charge'      => $orders['Order_transaction']['delivery_charge'],
                        'packing_charge'       => $orders['Order_transaction']['packing_charge'],
                        'amount'               => $orders['Order_transaction']['amount'],
                        'round'                => $orders['Order_transaction']['round'],
                        'name'                 => $orders['Order_transaction']['name'],
                        'phone'                => $orders['Order_transaction']['phone'],
                        'address'              => $orders['Order_transaction']['address'],
                        'remarks'              => $orders['Order_transaction']['remarks'],
                        'status'               => $orders['Order_transaction']['status'],
                        'tokenno'              => $orders['Order_transaction']['tokenno'],
                        'createtime'           => $orders['Order_transaction']['createtime'],
                        'created'              => $orders['Order_transaction']['created'],
                        'pax'                  => $orders['Order_transaction']['pax'],
                        'is_split'             => $orders['Order_transaction']['is_split'],
                        'split_count'          => $orders['Order_transaction']['split_count'],
                        'split_type'           => $orders['Order_transaction']['split_type'],
                        'kot_number'           => $kot_numbers
                    ];
                }
            }
            
            return json_encode([
                'status' => true,
                'is_split_bill' => false,
                'data' => $transactionitems
            ]);
        }
    }
    
    public function split_reprint_data()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $transactions = $this->Order_transaction->find('all', [
            'conditions' => ['reference_id' => $reference_id, 'status !=' => 0]
        ]);
        if (empty($transactions)){
            return json_encode([
                'status' => false,
                'message' => "Transaction Not Found"
            ]);
        }
        $order_punch_by='';
        
        if($transactions[0]['Order_transaction']['is_split']){
            $split_reference_id = $_REQUEST['split_reference_id'];
            
            $orderitems=[];
            $prodorderhistory_ids=[];
            $orderss = $this->Order_split_orderhistory->query("SELECT *,  ( SELECT name FROM users WHERE id = ( SELECT cashier_id FROM order_split_orderhistories WHERE reference_id = '$reference_id' and split_reference_id='$split_reference_id' AND status != 0 ORDER BY id ASC LIMIT 1 ) LIMIT 1 ) AS first_cashier_name  FROM `order_split_orderhistories` WHERE reference_id='$reference_id' and split_reference_id='$split_reference_id' and status!=0");
            if(!empty($orderss))
            {
                
                foreach($orderss as $orders){
                    $product_id=$orders['order_split_orderhistories']['product_id'];
                    $order_id=$orders['order_split_orderhistories']['order_history_id'];
                    $order_punch_by = $orders[0]['first_cashier_name'];
                
                    $prodorderhistory_ids[]=$orders['order_split_orderhistories']['order_history_id'];
                    $selected_modifiers=[];
                    
                    $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                    foreach($orders_modifiers as $orders_modifier){
                        
                        $modifiers=$orders_modifier['order_modifier'];
                        $modifier_group_id=$modifiers['modifier_group_id'];
                        $modifier_group_name=$modifiers['modifier_group_name'];
                        $modifier_id=$modifiers['modifier_id'];
                        $modifier_name=$modifiers['modifier_name'];
                        $modifier_price=$modifiers['modifier_price'];
                        
                        $selected_modifiers[]=array(
                            'modifier_group_id' => $modifier_group_id,
                            'modifier_group_name' => $modifier_group_name,
                            'modifier_id' => $modifier_id,
                            'modifier_name' => $modifier_name,
                            'modifier_price' => $modifier_price,
                            );
                        
                    }
                    
                    if(!isset($orders['order_split_orderhistories']['remarks'])){
                        $orders['order_split_orderhistories']['remarks']='';
                    }
                    $orderitems[]=array(
                        'id' => $orders['order_split_orderhistories']['id'],
                        'order_history_id' => $orders['order_split_orderhistories']['order_history_id'],
                        'reference_id' =>  $orders['order_split_orderhistories']['reference_id'],
                        'split_reference_id' =>  $orders['order_split_orderhistories']['split_reference_id'],
                        'cashier_id' =>  $orders['order_split_orderhistories']['cashier_id'],
                        'group_id' =>  $orders['order_split_orderhistories']['group_id'],
                        'category' =>  $orders['order_split_orderhistories']['category'],
                        'category_name' =>  $orders['order_split_orderhistories']['category_name'],
                        'kot_number' =>  $orders['order_split_orderhistories']['kot_number'],
                        'kds' =>  $orders['order_split_orderhistories']['kds'],
                        'product_id' =>  $orders['order_split_orderhistories']['product_id'],
                        'product_name' =>  $orders['order_split_orderhistories']['product_name'],
                        'quantity' =>  $orders['order_split_orderhistories']['quantity'],
                        'price' =>  $orders['order_split_orderhistories']['price'],
                        'total_tax' =>  $orders['order_split_orderhistories']['total_tax'],
                        'total_price' =>  $orders['order_split_orderhistories']['total_price'],
                        'discount' =>  $orders['order_split_orderhistories']['discount'],
                        'table_number' =>  $orders['order_split_orderhistories']['table_number'],
                        'remarks' =>  $orders['order_split_orderhistories']['remarks'],
                        'selected_modifiers' => $selected_modifiers,
                        'status' =>  $orders['order_split_orderhistories']['status'],
                        'created' =>  $orders['order_split_orderhistories']['created']
                    );
                }
            }
            $finalamount=0;
            $transactionitems=[];
            
            $transactions = $this->Order_split_transaction->query("
                SELECT 
                    ost.*,
                    SUM(ost.amount) AS total_amount
                FROM order_split_transactions ost
                WHERE ost.reference_id = '$reference_id' and ost.split_reference_id = '$split_reference_id'
                  AND ost.status != 0
            ");
            
            // ----------------------------------------
            // CHECK RESULT
            // ----------------------------------------
            if (!empty($transactions)) {
            
                foreach ($transactions as $row) {
            
                    // SQL fields come under numeric index (0)
                    $sqlData   = $row[0];
                    $transData = $row['ost'];
            
                    // remarks safe
                    if (empty($transData['remarks'])) {
                        $transData['remarks'] = '';
                    }
            
                    // Calculate final amount from SUM()
                    $finalamount  = $sqlData['total_amount'];
            
                    // Do NOT overwrite $reference_id; store local
                    $refIdLocal   = $transData['reference_id'];
                    $cashierid    = $transData['cashier_id'];
            
                    // ------------------------------------------------
                    // FETCH DISCOUNT PERCENTAGE
                    // ------------------------------------------------
                    $discper = $this->Order_tax->query("
                        SELECT discount_percentage 
                        FROM order_tax 
                        WHERE reference_id = '$refIdLocal'
                          AND status != 0 
                          AND discount_percentage != 0 
                        LIMIT 1
                    ");
            
                    $discount_percentage = (!empty($discper))
                        ? number_format($discper[0]['order_tax']['discount_percentage'], 2)
                        : "0";
            
                    // ------------------------------------------------
                    // FETCH KOT NUMBERS
                    // ------------------------------------------------
                    $kotQuery = $this->Order_split_orderhistory->query("
                        SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                        FROM order_split_orderhistories 
                        WHERE reference_id = '$refIdLocal' and split_reference_id = '$split_reference_id'
                          AND status != 0
                    ");
            
                    $kot_numbers = (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers']))
                        ? $kotQuery[0][0]['kot_numbers']
                        : '';
            
                    // ------------------------------------------------
                    // FINAL RESPONSE ENTRY
                    // ------------------------------------------------
                    $transactionitems[] = array(
                        'id'                     => $transData['id'],
                        'reference_id'           => $transData['reference_id'],
                        'split_reference_id'     => $transData['split_reference_id'],
                        'orderno'                => $transData['orderno'],
                        'device_id'              => $transData['device_id'],
                        'cashier_id'             => $transData['cashier_id'],
                        'table_number'           => $transData['table_number'],
                        'price'                  => $transData['price'],
                        'total_tax'              => $transData['total_tax'],
                        'servicecharge'          => $transData['servicecharge'],
                        'discount'               => $transData['discount'],
                        'discount_percentage'    => $discount_percentage,
                        'discount_type'          => $transData['discount_type'],
                        'discount_type_value'    => $transData['discount_type_value'],
                        'taxable_amount'         => number_format(($transData['price'] + $transData['servicecharge'])- $transData['discount'],2),
                        'delivery_charge'        => $transData['delivery_charge'],
                        'packing_charge'         => $transData['packing_charge'],
                        'amount'                 => $finalamount,
                        'round'                  => $transData['round'],
                        'name'                   => $transData['name'],
                        'phone'                  => $transData['phone'],
                        'address'                => $transData['address'],
                        'tokenno'                => $transData['tokenno'],
                        'createtime'             => $transData['createtime'],
                        'created'                => $transData['created'],
                        'pax'                    => $transData['pax'],
                        'status'                 =>  $transData['status'],
                        'waiter_id'              => $transData['waiter_id'],
                        'waiter_name'            => $transData['waiter_name'],
                        'is_takeaway'            => $transData['is_takeaway'],
                        'remarks'                => $transData['remarks'],
                        'kot_number'            => $kot_numbers,
                    );
                }
            }
    
            $paymentitems = [];
            // ----------------------------------------
            // SQL QUERY (supports split logic + grouping)
            // ----------------------------------------
            $payments = $this->Order_split_payment->query("
                SELECT 
                    osp.*
                FROM order_split_payments osp
                WHERE osp.reference_id = '$reference_id' and osp.split_reference_id = '$split_reference_id'
                  AND osp.status != 0
            ");
            
            
            // ----------------------------------------
            // LOOP PAYMENTS
            // ----------------------------------------
            if (!empty($payments)) {
            
                foreach ($payments as $row) {
            
                    // SQL fields
                    $payData  = $row['osp'];
            
                    // Safe remarks
                    if (empty($payData['remarks'])) {
                        $payData['remarks'] = '';
                    }
            
                    // FINAL payment item
                    $paymentitems[] = array(
                        'id'            => $payData['main_payment_id'],
                        'split_pay_id'   => $payData['id'] ?? '0',
                        'reference_id'  => $payData['reference_id'],
                        'split_reference_id'  => $payData['split_reference_id'] ?? '0',
                        'cashier_id'    => $payData['cashier_id'],
                        'type'          => $payData['type'],
                        'type_value'    => $payData['type_value'],
                        'amount'        => $payData['amount'], 
                        'status'        => $payData['status'],
                        'remarks'       => $payData['remarks'],
                        'created'       => $payData['created']
                    );
                }
            }
    
            $taxitems = [];
            $ids = implode(',', array_map('intval', $prodorderhistory_ids));
            
            $taxes=[];
            if($ids){
                // ------------------------------------------------------
                // SPLIT-SAFE TAX QUERY (GROUP BY tax_id)
                // ------------------------------------------------------
                $taxes = $this->Order_tax->query("
                    SELECT 
                        ost.tax_id,
                        ost.tax_name,
                        ost.tax_percentage,
                        SUM(ost.tax_value) AS tax_value
                    FROM order_tax ost
                    WHERE ost.reference_id = '$reference_id' and ost.orderhistory_id IN ($ids)
                      AND ost.status != 0
                    GROUP BY ost.tax_id
                ");
            }
            
            // ------------------------------------------------------
            // BUILD JSON RESPONSE
            // ------------------------------------------------------
            if (!empty($taxes)) {
            
                foreach ($taxes as $row) {
            
                    $sql = $row[0];                     // aggregated fields
                    $tax = $row['ost'];     // row fields
            
                    $taxitems[] = array(
                        'tax_id'        => $tax['tax_id'],
                        'tax_name'      => $tax['tax_name'],
                        'tax_percentage'=> $tax['tax_percentage'],
                        'tax_value'     => (string) round($sql['tax_value'], 2)
                    );
                }
            }
    
            $finalpayment=0;
            $allpayments=$this->Order_split_payment->query("SELECT sum(amount) as pay_amount FROM `order_split_payments` WHERE reference_id='$reference_id' and split_reference_id = '$split_reference_id' and status!=0");
            if($allpayments){
                $finalpayment=$allpayments[0][0]['pay_amount'];
            }
            $amount_diff=round(($finalamount-$finalpayment),2);
        
        }else{
            
            $orderitems=[];
            $orderss = $this->Order_orderhistory->query("SELECT *,  ( SELECT name FROM users WHERE id = ( SELECT cashier_id FROM order_orderhistories WHERE reference_id = '$reference_id' AND status != 0 ORDER BY id ASC LIMIT 1 ) LIMIT 1 ) AS first_cashier_name  FROM `order_orderhistories` WHERE reference_id='$reference_id' and status!=0");
            if(!empty($orderss))
            {
                foreach($orderss as $orders){
                    $product_id=$orders['order_orderhistories']['product_id'];
                    $order_id=$orders['order_orderhistories']['id'];
                    $order_punch_by = $orders[0]['first_cashier_name'];
                
                    $selected_modifiers=[];
                    $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status!=0");
                    foreach($orders_modifiers as $orders_modifier){
                        
                        $modifiers=$orders_modifier['order_modifier'];
                        $modifier_group_id=$modifiers['modifier_group_id'];
                        $modifier_group_name=$modifiers['modifier_group_name'];
                        $modifier_id=$modifiers['modifier_id'];
                        $modifier_name=$modifiers['modifier_name'];
                        $modifier_price=$modifiers['modifier_price'];
                        
                        $selected_modifiers[]=array(
                            'modifier_group_id' => $modifier_group_id,
                            'modifier_group_name' => $modifier_group_name,
                            'modifier_id' => $modifier_id,
                            'modifier_name' => $modifier_name,
                            'modifier_price' => $modifier_price,
                            );
                        
                    }
                    
                    if(!isset($orders['order_orderhistories']['remarks'])){
                        $orders['order_orderhistories']['remarks']='';
                    }
                    $orderitems[]=array(
                        'id' => $orders['order_orderhistories']['id'],
                        'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                        'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                        'group_id' =>  $orders['order_orderhistories']['group_id'],
                        'category' =>  $orders['order_orderhistories']['category'],
                        'category_name' =>  $orders['order_orderhistories']['category_name'],
                        'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                        'kds' =>  $orders['order_orderhistories']['kds'],
                        'product_id' =>  $orders['order_orderhistories']['product_id'],
                        'product_name' =>  $orders['order_orderhistories']['product_name'],
                        'quantity' =>  $orders['order_orderhistories']['quantity'],
                        'price' =>  $orders['order_orderhistories']['price'],
                        'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                        'total_price' =>  $orders['order_orderhistories']['total_price'],
                        'discount' =>  $orders['order_orderhistories']['discount'],
                        'table_number' =>  $orders['order_orderhistories']['table_number'],
                        'remarks' =>  $orders['order_orderhistories']['remarks'],
                        'selected_modifiers' => $selected_modifiers,
                        'status' =>  $orders['order_orderhistories']['status'],
                        'created' =>  $orders['order_orderhistories']['created']
                    );
                }
            }
            $finalamount=0;
            $transactionitems=[];
            $transactions = $this->Order_transaction->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
            if(!empty($transactions))
            {
                foreach($transactions as $orders){
                    if(!$orders['Order_transaction']['remarks']){
                        $orders['Order_transaction']['remarks']='';
                    }
                    $finalamount=$orders['Order_transaction']['amount'];
                    $cashierid=$orders['Order_transaction']['cashier_id'];
                    $reference_id=$orders['Order_transaction']['reference_id'];
                    
                    $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                    if(!empty($discper))
                    {
                        $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                    }
                    if(!isset($discount_percentage)){
                        $discount_percentage="0";
                    }
                    
                    // 🔹 Get KOT numbers
                    $kotQuery = $this->Order_orderhistory->query("
                        SELECT GROUP_CONCAT(DISTINCT(kot_number)) AS kot_numbers 
                        FROM order_orderhistories 
                        WHERE reference_id = '$reference_id' and status!=0
                    ");
            
                    $kot_numbers = '';
                    if (!empty($kotQuery) && isset($kotQuery[0][0]['kot_numbers'])) {
                        $kot_numbers = $kotQuery[0][0]['kot_numbers'];
                    }
            
                    $transactionitems[]=array(
                        'id' => $orders['Order_transaction']['id'],
                        'reference_id' =>  $orders['Order_transaction']['reference_id'],
                        'split_reference_id'     => '0',
                        'orderno' =>  $orders['Order_transaction']['orderno'],
                        'device_id' =>  $orders['Order_transaction']['device_id'],
                        'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                        'table_number' =>  $orders['Order_transaction']['table_number'],
                        'price' =>  $orders['Order_transaction']['price'],
                        'total_tax' =>  $orders['Order_transaction']['total_tax'],
                        'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                        'discount' =>  $orders['Order_transaction']['discount'],
                        'discount_percentage' =>  $discount_percentage,
                        'discount_type' =>  $orders['Order_transaction']['discount_type'],
                        'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                        'taxable_amount' => number_format(($orders['Order_transaction']['price'] + $orders['Order_transaction']['servicecharge']) - $orders['Order_transaction']['discount'],2),
                        'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                        'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                        'amount' =>  $orders['Order_transaction']['amount'],
                        'round' =>  $orders['Order_transaction']['round'],
                        'name' =>  $orders['Order_transaction']['name'],
                        'phone' =>  $orders['Order_transaction']['phone'],
                        'address' =>  $orders['Order_transaction']['address'],
                        'remarks' =>  $orders['Order_transaction']['remarks'],
                        'status' =>  $orders['Order_transaction']['status'],
                        'tokenno' =>  $orders['Order_transaction']['tokenno'],
                        'createtime' =>  $orders['Order_transaction']['createtime'],
                        'created' =>  $orders['Order_transaction']['created'],
                        'pax' =>  $orders['Order_transaction']['pax'],
                        'is_split'             => $orders['Order_transaction']['is_split'],
                        'split_count'          => $orders['Order_transaction']['split_count'],
                        'split_type'           => $orders['Order_transaction']['split_type'],
                        'kot_number' => $kot_numbers
                    );
                }
            }
            $paymentitems=[];
            $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status !='=>0)));
            if(!empty($payments))
            {
                foreach($payments as $orders){
                    if(!isset($orders['Order_payment']['remarks'])){
                        $orders['Order_payment']['remarks']='';
                    }
                    $paymentitems[]=array(
                        'id' => $orders['Order_payment']['id'],
                        'split_pay_id' => '0',
                        'split_reference_id' => '0',
                        'reference_id' =>  $orders['Order_payment']['reference_id'],
                        'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                        'type' =>  $orders['Order_payment']['type'],
                        'type_value' =>  $orders['Order_payment']['type_value'],
                        'amount' =>  $orders['Order_payment']['amount'],
                        'status' =>  $orders['Order_payment']['status'],
                        'remarks' =>  $orders['Order_payment']['remarks'],
                        'created' =>  $orders['Order_payment']['created']
                    );
                }
            }
            $taxitems=[];
            $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");
            if(!empty($taxes))
            {
                foreach($taxes as $tax){
                    $taxitems[]=array(
                        'tax_id' => $tax['order_tax']['tax_id'],
                        'tax_name' =>  $tax['order_tax']['tax_name'],
                        'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                        'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                    );
                }
            }
            $finalpayment=0;
            $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
            if($allpayments){
                $finalpayment=$allpayments[0][0]['pay_amount'];
            }
            $amount_diff=round(($finalamount-$finalpayment),2);
        }
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'order_punch_by'=>$order_punch_by,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }

    public function split_orderpaymentsave_table()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
    
        if (isset($_REQUEST['data'])) {
            $data = $_REQUEST['data'];
        } else {
            $response =array(
                'status'=> false,
                'message'=> "data not found",
            );
            return json_encode($response);
        }
        
        $data = json_decode($data, true);
        
        $reference_id=$data['reference_id'];
        $device_id=$data['device_id'];
        
        //payment save
        
        $transactions = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$reference_id,'Order_transaction.status'=>1)));
        if(empty($transactions))
        {
            $response =array(
                'status'=> false,
                'message'=> "Transaction not found",
            );
            return json_encode($response);
        }
        
        $store_id=$transactions['Order_transaction']['store_id'];
        $is_split=$transactions['Order_transaction']['is_split'];
        
        if($is_split){
            $split_id=$data['id'];
            $split_reference_id=$data['split_reference_id'];
                
            $splittransactions = $this->Order_split_transaction->find('all', [
                'fields' => [
                    'Order_split_transaction.*',
                    'SUM(Order_split_transaction.amount) AS total_amount'
                ],
                'conditions' => [
                    'Order_split_transaction.reference_id' => $reference_id,
                    'Order_split_transaction.split_reference_id' => $split_reference_id,
                    'Order_split_transaction.id' => $split_id,
                    'Order_split_transaction.status' => 1
                ]
            ]);
            
            if (empty($splittransactions[0]['Order_split_transaction']['id'])) {
                $response =array(
                    'status'=> false,
                    'message'=> "No Split Transaction found",
                );
                return json_encode($response);
            }
            
            foreach($data['payment'] as $payment){
                
                if($payment['type']==7){
                    $response['status']= false;
                    $response['message']= "Option not allowed";
                    return json_encode($response);
                }
                
                
                $split_finalamount = $splittransactions[0][0]['total_amount'];
         
                $datas['Order_split_payment']=array(
                    'split_reference_id'=>$split_reference_id,
                    'split_txn_id'=>$split_id,
                    'reference_id'=>$reference_id,
                    'store_id'=>$store_id,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'type'=>$payment['type'],
                    'type_value'=>$payment['type_value'],
                    'amount'=>$payment['amount'],
                    'remarks'=>$payment['remarks']
                );
                
                if($this->Order_split_payment->saveAll($datas['Order_split_payment']))
                {
                    $splitPaymentId = $this->Order_split_payment->id;

                    $split_allpayments=$this->Order_split_payment->query("SELECT sum(amount) as pay_amount FROM `order_split_payments` WHERE split_txn_id='$split_id' and split_reference_id='$split_reference_id' and reference_id='$reference_id' and status!=0");
                    if($split_allpayments){
                        $split_finalpayment=$split_allpayments[0][0]['pay_amount'];
                    }
                    $split_amount_diff=round(($split_finalamount-$split_finalpayment),2);
                    
                    if($split_amount_diff<1){
                        $this->Order_split_orderhistory->query("UPDATE order_split_orderhistories SET status = 2,sync=0,local_sync=0 WHERE split_reference_id='$split_reference_id' and reference_id = '$reference_id' and status = 1");
                        $this->Order_split_transaction->query("UPDATE order_split_transactions SET status = 2,payment_mode='$type_value',sync=0,local_sync=0 WHERE id='$split_id' and split_reference_id='$split_reference_id' and reference_id = '$reference_id' and status!=0");
                        $this->Order_split_payment->query("UPDATE order_split_payments SET status = 2,sync=0,local_sync=0 WHERE split_txn_id='$split_id' and split_reference_id='$split_reference_id' and reference_id = '$reference_id' and status!=0");
                    }
                    
                    $datas['Order_payment']=array(
                        'reference_id'=>$reference_id,
                        'store_id'=>$store_id,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'type'=>$payment['type'],
                        'type_value'=>$payment['type_value'],
                        'amount'=>$payment['amount'],
                        'remarks'=>$payment['remarks']
                    );
                    if($this->Order_payment->saveAll($datas['Order_payment']))
                    {
                        $mainpayid = $this->Order_payment->id;

                        $this->Order_split_payment->query("UPDATE order_split_payments SET main_payment_id = '$mainpayid',sync=0,local_sync=0 WHERE id='$splitPaymentId' and split_reference_id='$split_reference_id' and reference_id = '$reference_id' and status!=0");
                        
                        $finalpayment=0;
                        $finalamount=0;
                        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
                        if($allpayments){
                            $finalpayment=$allpayments[0][0]['pay_amount'];
                        }
                        if($transactions){
                            $finalamount=$transactions['Order_transaction']['amount'];
                        }
                        $amount_diff=$finalamount-$finalpayment;
                        if($amount_diff<1){
                            
                            $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                            $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='$type_value',sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                            $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                            $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                            
                            do {
                                $pin = 'TX' . $cashierid . date('Y') . uniqid();
                                // $pin = uniqid();
                            } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
                            
                            $tablestatus = $this->Order_table->find('first', array('conditions'=>array('reference_id'=>$reference_id,'is_takeaway'=>1)));
                            if(!empty($tablestatus))
                            {   
                                $this->Order_table->query("UPDATE order_tables SET status=0,sync=0,local_sync=0,modified=NOW()  WHERE reference_id = '$reference_id'");
                            }else{
                                $this->Order_table->query("UPDATE order_tables SET customer_name='',customer_phone='',customer_address='',customer_pax=1,status = 1,reference_id='$pin',is_alert=0,sync=0,local_sync=0,modified=NOW() WHERE reference_id = '$reference_id'");
                            }
        
                            $stockupdate=$this->stock_update($reference_id);
                            if(!$stockupdate){
                                $response['status']= true;
                                $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                                $response['full_payment']= true; 
                            }
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..!";
                            $response['full_payment']= true;
                        }else{
                            if($split_amount_diff<1){
                                $response['status']= true;
                                $response['message']= "Payment Data Saved Successfully..!";
                                $response['full_payment']= true;
                            }else{
                                $response['status']= true;
                                $response['message']= "Payment Data Saved Successfully..!";
                                $response['full_payment']= false;
                            }
                        }
                    }
                }else{
                    $response['status']= false;
                    $response['message']= "Payment Data not saved Error:102";
                    $response['full_payment']= false;
                }
            }
        }else{
            
            foreach($data['payment'] as $payment){
                $datas['Order_payment']=array(
                    'reference_id'=>$reference_id,
                    'store_id'=>$store_id,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'type'=>$payment['type'],
                    'type_value'=>$payment['type_value'],
                    'amount'=>$payment['amount'],
                    'remarks'=>$payment['remarks']
                );
                if($this->Order_payment->saveAll($datas['Order_payment']))
                {
                    $finalpayment=0;
                    $finalamount=0;
                    $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status!=0");
                    if($allpayments){
                        $finalpayment=$allpayments[0][0]['pay_amount'];
                    }
                    if($transactions){
                        $finalamount=$transactions['Order_transaction']['amount'];
                    }
                    $amount_diff=$finalamount-$finalpayment;
                    if($amount_diff<1){
                        
                        $this->Order_orderhistory->query("UPDATE order_orderhistories SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status = 1");
                        $this->Order_transaction->query("UPDATE order_transactions SET status = 2,payment_mode='$type_value',sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                        $this->Order_payment->query("UPDATE order_payments SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status!=0");
                        $this->Order_tax->query("UPDATE order_tax SET status = 2,sync=0,local_sync=0 WHERE reference_id = '$reference_id' and status != 0");
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_table->find('first', array('fields' => 'Order_table.id', 'conditions' => array('Order_table.reference_id' => $pin))));
                        
                        $tablestatus = $this->Order_table->find('first', array('conditions'=>array('reference_id'=>$reference_id,'is_takeaway'=>1)));
                        if(!empty($tablestatus))
                        {   
                            $this->Order_table->query("UPDATE order_tables SET status=0,sync=0,local_sync=0,modified=NOW()  WHERE reference_id = '$reference_id'");
                        }else{
                            $this->Order_table->query("UPDATE order_tables SET customer_name='',customer_phone='',customer_address='',customer_pax=1,status = 1,reference_id='$pin',is_alert=0,sync=0,local_sync=0,modified=NOW() WHERE reference_id = '$reference_id'");
                        }
    
                        $stockupdate=$this->stock_update($reference_id);
                        if(!$stockupdate){
                            $response['status']= true;
                            $response['message']= "Payment Data Saved Successfully..! But stock not updated";
                            $response['full_payment']= true; 
                        }
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= true;
                    }else{
                        $response['status']= true;
                        $response['message']= "Payment Data Saved Successfully..!";
                        $response['full_payment']= false;
                    }
                }else{
                    $response['status']= false;
                    $response['message']= "Payment Data not saved Error:102";
                    $response['full_payment']= false;
                }
            }
        }
        return json_encode($response);
    }
    

    public function item_move_multiple()
    {
        $this->autoRender = false;
    
        // ---------------------------
        // Read Inputs Safely
        // ---------------------------
        $cashierid         = trim($_REQUEST['id'] ?? '');
        $from_reference_id = trim($_REQUEST['from_reference_id'] ?? '');
        $to_reference_id   = trim($_REQUEST['to_reference_id'] ?? '');
    
        // ---------------------------
        // Basic Validation
        // ---------------------------
        if (!$cashierid) {
            return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        }
        if (!$from_reference_id) {
            return json_encode(['status' => false, 'message' => 'From Reference ID is missing']);
        }
        if (!$to_reference_id) {
            return json_encode(['status' => false, 'message' => 'To Reference ID is missing']);
        }
    
        // ---------------------------
        // Validate User
        // ---------------------------
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive'  => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
    
        // ---------------------------
        // Validate Tables
        // ---------------------------
        $fromtable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $from_reference_id,
                'Order_table.status'       => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($fromtable)) {
            return json_encode(['status' => false, 'message' => 'From Table not available for Item Move']);
        }
    
        $totable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $to_reference_id,
                'Order_table.status'       => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($totable)) {
            return json_encode(['status' => false, 'message' => 'To Table not available for Item Receive']);
        }
    
        // ---------------------------
        // Decode JSON
        // ---------------------------
        $json = json_decode($_REQUEST['data'] ?? '', true);
    
        if ($json === null) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON']);
        }
    
        if (empty($json['order_ids']) || !is_array($json['order_ids'])) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON structure: order_ids missing']);
        }
    
        // ---------------------------
        // Process Items (STOP on ANY ERROR)
        // ---------------------------
        $updated = false;
        $to_table_number = $totable['Order_table']['number'];
    
        foreach ($json['order_ids'] as $item) {
    
            // ❌ If order_id missing → STOP
            if (empty($item['order_id'])) {
                return json_encode(['status' => false, 'message' => 'Order ID missing in request']);
            }
    
            $order_id = (int)$item['order_id'];
    
            // Fetch order at from table
            $order = $this->Order_orderhistory->find('first', [
                'conditions' => [
                    'Order_orderhistory.id'            => $order_id,
                    'Order_orderhistory.reference_id'  => $from_reference_id,
                    'Order_orderhistory.status !='     => 0
                ],
                'recursive' => -1
            ]);
    
            // ❌ If order not found → STOP
            if (empty($order)) {
                return json_encode(['status' => false, 'message' => 'Item not available for movement']);
            }
    
            // Move TAX records
            $this->Order_tax->updateAll(
                [
                    'Order_tax.reference_id' => "'$to_reference_id'",
                    'Order_tax.sync'            => 0,
                    'Order_tax.local_sync'      => 0
                ],
                [
                    'Order_tax.orderhistory_id' => $order_id,
                    'Order_tax.reference_id'    => $from_reference_id,
                    'Order_tax.status !='      => 0
                ]
            );
            
            $this->Kds_track->updateAll(
                array(
                    'Kds_track.order_reference_id' => "'$to_reference_id'",
                    'Kds_track.table_no' => "'$to_table_number'",
                    'Kds_track.sync' => 0,
                    'Kds_track.local_sync' => 0
                ),
                array(
                    'Kds_track.order_history_id' => (int)$order_id,
                    'Kds_track.order_reference_id' => $from_reference_id,
                    'Kds_track.status !=' => 0
                )
            );
            
            // Update modifier reference
            $this->Order_modifier->updateAll(
                array(
                    'Order_modifier.reference_id' => "'$to_reference_id'",
                    'Order_modifier.sync' => 0,
                    'Order_modifier.local_sync' => 0
                ),
                array(
                    'Order_modifier.orderhistory_id' => (int)$order_id,
                    'Order_modifier.reference_id' => $from_reference_id,
                    'Order_modifier.status !=' => 0
                )
            );
            
            // Move ORDER item
            $res = $this->Order_orderhistory->updateAll(
                [
                    'Order_orderhistory.reference_id' => "'$to_reference_id'",
                    'Order_orderhistory.table_number' => "'$to_table_number'",
                    'Order_orderhistory.sync'         => 0,
                    'Order_orderhistory.local_sync'   => 0
                ],
                [
                    'Order_orderhistory.id'           => $order_id,
                    'Order_orderhistory.reference_id' => $from_reference_id,
                    'Order_orderhistory.status !='   => 0
                ]
            );
    
            if ($res) {
                $updated = true;
            }
        }
    
        // ---------------------------
        // Final Response
        // ---------------------------
        if ($updated) {
            return json_encode(['status' => true, 'message' => 'Item(s) moved successfully']);
        }
    
        return json_encode(['status' => false, 'message' => 'No items moved']);
    }
    
    public function bill_table_package_discount()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        
        $disc=$_REQUEST['discount'];
        $type = $_REQUEST['type'];
        $dish_type = $_REQUEST['kds'];
        $sc = $_REQUEST['service_charge'] ?? 0;
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        
        if($type==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Type Missing",
            );
            return json_encode($response);
        }
        
        if($dish_type==''){
            $response =array(
                'status'=> false,
                'message'=> "Dish Type Missing",
            );
            return json_encode($response);
        }
        
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['customer_pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];
        
        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'              => 0,
                'Order_table.local_sync'        => 0
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
        
        $refid = []; // T9-fix: no merged tables guard

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                    
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
               
                $round_amount = $finalamount - $roundfinalamount;
                
                $datas['Order_transaction']=array(
                    'reference_id'=>$table_referenceid,
                    'device_id'=>$device_id,
                    'cashier_id'=>$cashierid,
                    'store_id'=>$location_id,
                    'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                    'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                    'discount'=>round($orderss[0][0]['discount'],2),
                    'discount_items'=>$dish_type,
                    'amount'=>$finalamount,
                    'round'=>round($round_amount,2),
                    'name'=>$name,
                    'phone'=>$phone,
                    'address'=>$address,
                    'tokenno'=>$token,
                    'table_number'=>$table_number,
                    'pax'=>$pax,
                    'waiter_id'=>$waiter_id,
                    'waiter_name'=>$waiter_name,
                    'is_takeaway' => $is_takeaway,
                    'createtime'=>$currenttime
                );
                if($this->Order_transaction->saveAll($datas['Order_transaction']))
                {
                    $this->Order_table->query("UPDATE order_tables SET status = 3,sync=0,local_sync=0 WHERE reference_id = '$table_referenceid' and status!=0");
                    $this->Order_table->query("UPDATE order_tables SET status = 1,sync=0,local_sync=0 WHERE reference_id IN ($refid)  and status!=0");
                    $this->Order_table_tracking->query("UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0 WHERE merged_table_ref_id IN ($refid)");

                    if (!$this->bill_table_package_kds_discount($cashierid,$table_referenceid,$disc,$sc,$type,$dish_type)) {
                    
                        return json_encode([
                            'status'  => false,
                            'message' => "Discount not saved",
                        ]);
                    }
                    
                    $response['status']= true;
                    $response['message']= "Bill Generated Successfully..!";
                }else{
                    $response['status']= false;
                    $response['message']= "Transaction Data not saved Error:103";
                }
            }
        
        return json_encode($response);
    }
    
    public function bill_table_package_kds_discount($cashierid,$ref_id,$disc,$sc,$type,$dish_type)
    {
        $todayDate = date("Y-m-d");
        
        $discount_type_value=$disc;
        
        $retry = false;   // 🔒 prevents second retry in same execution

        // if($dish_type==='all'){
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1
        //     ");
    
        //     if(!empty($kdss)){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        // }
        // else{
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1 
        //         AND dish_type=$dish_type
        //     ");
    
        //     if (!empty($kdss) && !empty($kdss[0][0]['kds'])){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        //     else{
        //         return json_encode([
        //             'status'=> false,
        //             'message'=> "No kds found for this dish type",
        //         ]);
        //     }
        // }
    
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', [
                    'conditions'=>[
                        'Coupon.code'=>$disc,
                        'Coupon.expiry_date >='=>$todayDate,
                        'Coupon.status'=>1
                    ]
                ]);
    
                if(empty($coup)){
                    return json_encode([
                        'status'=> false,
                        'message'=> "Coupon not found Or Coupon Expired",
                    ]);
                }
    
                $disc=$coup['Coupon']['value'];
            }
            else{
                $disc=0;
            }
        }
    
        if($type==1){
            $disc=$disc;
        }
    
        if($type==2){
    
            if($dish_type==='all'){
                $subtotals = $this->Order_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id'
                ");
            }
            else{
                $subtotals = $this->Order_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id' 
                    AND dish_type=$dish_type
                ");
            }
    
            if($subtotals){
                $subtotal = $subtotals[0][0]['subtotal'];
    
                if($subtotal){
                    $disc = round((($disc * 100) / $subtotal),2);
                }
                else{
                    return json_encode([
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    ]);
                }
            }
            else{
                return json_encode([
                    'status'=> false,
                    'message'=> "Bill Not Found",
                ]);
            }
        }
    
        if($disc > 99){
            return json_encode([
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            ]);
        }
    
        // $kdsarray = explode(",", $kds);
    
        // if($dish_type!='all'){
        //     $kdschk = $this->Pos_printer->find('first', [
        //         'conditions'=>['Pos_printer.kds'=>$kdsarray,'Pos_printer.status'=>1]
        //     ]);
    
        //     if(empty($kdschk)){
        //         return json_encode([
        //             'status'=> false,
        //             'message'=> "KDS not found while applying discount",
        //         ]);
        //     }
        // }
    
        if($dish_type!='all'){
            // $kdschk = $this->Order_orderhistory->find('first', [
            //     'conditions'=>[
            //         'Order_orderhistory.reference_id'=>$ref_id,
            //         'Order_orderhistory.kds'=>$kdsarray,
            //         'Order_orderhistory.status !='=>0
            //     ]
            // ]);
            $kdschk = $this->Order_orderhistory->find('first', [
                'conditions' => [
                    'Order_orderhistory.reference_id' => $ref_id,
                    'Order_orderhistory.status !=' => 0,
                    'Order_orderhistory.dish_type'=>$dish_type
                ]
            ]);
        }
        else{
            $kdschk = $this->Order_orderhistory->find('first', [
                'conditions'=>[
                    'Order_orderhistory.reference_id'=>$ref_id,
                    'Order_orderhistory.status !='=>0
                ]
            ]);
        }
    
        if(empty($kdschk)){
            return json_encode([
                'status'=> false,
                'message'=> "No Item found for this KDS while applying discount.",
            ]);
        }
        
        $packagechk = $this->Order_orderhistory->find('first', [
            'conditions'=>[
                'Order_orderhistory.reference_id'=>$ref_id,
                'Order_orderhistory.package'=>1,
                'Order_orderhistory.status !='=>0
            ]
        ]);
    
        if(!empty($packagechk)){
            return json_encode([
                'status'=> false,
                'message'=> "You cannot merge Discount with package.",
            ]);
        }
    
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',[
                'conditions'=>[
                    'Order_orderhistory.discount > '=>0,
                    'Order_orderhistory.cashier_id'=>$cashierid,
                    'Order_orderhistory.status'=>2,
                    'Order_orderhistory.reference_id'=>$ref_id
                ]
            ]);
    
            if(!empty($checkdiscount)){
                return json_encode([
                    'status'=> false,
                    'message'=> "Discount cannot merge with item level discount"
                ]);
            }
        }
        else{
            return json_encode([
                'status'=> false,
                'message'=> "Please check discount value"
            ]);
        }
        
        if($dish_type==='all'){
            $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
        }else{
            $this->Order_tax->query("UPDATE order_tax SET discount_percentage='0',sync=0,local_sync=0 WHERE reference_id = '$ref_id'");
            $orderdata=$this->ordercomputewithkds($ref_id,$cashierid,$sc,$disc,$dish_type);
        }
    
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $exactTotalAmount=(($totalprice+$totaltax+$totalservicechg)-$totaldiscount); //483
            $round2TotalAmount = round($exactTotalAmount, 2);   // 2 decimal value //
            $finalTotalAmount  = round($exactTotalAmount);      // nearest integer
            $roundOffAmount    = round($finalTotalAmount - $round2TotalAmount, 2);
    
            $createtime = date('H:i:s');
            
            $this->Order_transaction->query("
                UPDATE order_transactions 
                SET 
                    price = '$totalprice',
                    total_tax='$totaltax',
                    servicecharge='$totalservicechg',
                    discount='$totaldiscount',
                    discount_type='$type',
                    discount_type_value='$discount_type_value',
                    amount='$finalTotalAmount',
                    round='$roundOffAmount',
                    createtime='$createtime',sync=0,local_sync=0
                WHERE reference_id = '$ref_id' and status!=0
            ");
            
            if ($disc > 0 && $retry === false) {
                
                // Check if we already attempted safety net for this reference (prevents repeated attempts)
                $transactionCheck = $this->Order_transaction->find('first', array(
                    'conditions' => array(
                        'Order_transaction.reference_id' => $ref_id,
                        'Order_transaction.status' => 1,
                        'Order_transaction.discount >'   => 0
                    ),
                    'fields' => array('id')
                ));
                
                // Only run safety net if transaction has discount but we haven't marked it as processed
                // The transaction discount being set means the main flow completed
                if (!empty($transactionCheck)) {
                    
                    $ordertaxCheck = $this->Order_tax->find('count', array(
                        'conditions' => array(
                            'Order_tax.reference_id' => $ref_id,
                            'Order_tax.discount_percentage >' => 0,
                            'Order_tax.status' => 1
                        ),
                        'fields' => array('id')
                    ));
                    
                    if(!empty($ordertaxCheck==0)){

                        $retry = true;

                        if($dish_type==='all'){
                            $orderdata=$this->ordercompute($ref_id,$cashierid,$sc,$disc);
                        }else{
                            $this->Order_tax->query("UPDATE order_tax SET discount_percentage='0',sync=0,local_sync=0 WHERE reference_id = '$ref_id'");
                            $orderdata=$this->ordercomputewithkds($ref_id,$cashierid,$sc,$disc,$dish_type);
                        }
                    }
                }
            }
            
            return json_encode([
                'status'=> true,
                'message'=> "Saved",
            ]);
        }
        else{
            return json_encode([
                'status'=> false,
                'message'=> "Not Saved",
            ]);
        }
    }
    
    /*
    public function split_bill_table_package_discount()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        
        $disc=$_REQUEST['discount'];
        $type = $_REQUEST['type'];
        $dish_type = $_REQUEST['kds'];
        $sc = $_REQUEST['service_charge'] ?? 0;
        
        if($disc==''){
            return json_encode([
                'status'=> false,
                'message'=> "Discount Missing",
            ]);
        }
        
        if($type==''){
            return json_encode([
                'status'=> false,
                'message'=> "Discount Type Missing",
            ]);
        }
        
        if($dish_type==''){
            return json_encode([
                'status'=> false,
                'message'=> "Dish Type Missing",
            ]);
        }
        
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        
        if (!isset($_REQUEST['data'])) {
            $response = array(
                'status' => false,
                'message' => "data not found",
            );
            return json_encode($response);
        }
        
        $data = json_decode($_REQUEST['data'], true);
        
        // Check if JSON is valid
        if ($data === null) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json'
            ]);
        }
        
        // Validate required structure
        if (
            !isset($data['splits']) ||
            !is_array($data['splits']) ||
            count($data['splits']) == 0
        ) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json structure: splits missing'
            ]);
        }
        
        foreach ($data['splits'] as $split) {
        
            // Check items key
            if (!isset($split['items']) || !is_array($split['items']) || count($split['items']) == 0) {
                return json_encode([
                    'status' => false,
                    'message' => 'invalid json structure: items missing'
                ]);
            }
        
            foreach ($split['items'] as $item) {
        
                if (
                    !isset($item['id']) ||
                    !isset($item['reference_id']) ||
                    !isset($item['quantity'])
                ) {
                    return json_encode([
                        'status' => false,
                        'message' => 'invalid json structure: item keys missing'
                    ]);
                }
            }
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        
        $orderQtyRes = $this->Order_orderhistory->query("
            SELECT id, SUM(quantity) as total_qty,product_name
            FROM order_orderhistories
            WHERE reference_id = '$table_referenceid'
              AND status != 0
            GROUP BY product_id
        ");
        $originalQty = [];
        
        foreach ($orderQtyRes as $row) {
            $itemId = $row['order_orderhistories']['id'];
            $originalQty[$itemId] = (int)$row[0]['total_qty'];
            $originalname[$itemId] = $row['order_orderhistories']['product_name'];
        }
        
        $splitQty = [];
        
        foreach ($data['splits'] as $split) {
            foreach ($split['items'] as $item) {
        
                $id = $item['id'];
                $qty = (int)$item['quantity'];
        
                if (!isset($splitQty[$id])) {
                    $splitQty[$id] = 0;
                }
        
                $splitQty[$id] += $qty;
            }
        }
        
        foreach ($originalQty as $itemId => $qtyFromOrder) {
        
            $qtyFromSplit = isset($splitQty[$itemId]) ? $splitQty[$itemId] : 0;
        
            if ($qtyFromSplit != $qtyFromOrder) {
                return json_encode([
                    'status' => false,
                    'message' => "Invalid quantity for {$originalName[$itemId]}: Ordered $qtyFromOrder, Given $qtyFromSplit"
                ]);
            }
        }

        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];

        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'              => 0,
                'Order_table.local_sync'        => 0
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
        
        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                
                $round_amount = $finalamount - $roundfinalamount;
                $split_count = count($data['splits']);
                
                $is_split=1;
                if($split_count==1){
                    $split_count=0;
                    $is_split=0;
                }
                
                $this->Order_transaction->begin();
                
                try {
                
                    // =========================================================
                    // 1. SAVE ALL SPLIT DETAILS (orderhistory + tax + split tx)
                    // =========================================================
                    
                    $series_id=sprintf("%02d", $cashierid);
                    $users=$this->User->find('first',array('conditions'=>array('id'=>$cashierid)));
                    $series=strtoupper(substr($users['User']['username'],0,2)); 

                    $ordertrx=$this->Order_transaction->query("SELECT orderno,split_count FROM `order_transactions` order by id desc limit 1");
                    
                    if($ordertrx[0]['order_transactions']['split_count']>1){
                     $last_split_count=$ordertrx[0]['order_transactions']['split_count']-1;
                    }else{
                     $last_split_count=0;
                    }
                     
                    $ordernewstring = substr($ordertrx[0]['order_transactions']['orderno'], -8) + $last_split_count;
                    $ordernonewno=$ordernewstring+1;
                    
                    foreach ($data['splits'] as $block) {
                
                        $refId = null;
                        $blockAmount = 0;   // initialize
                        $blockTax    = 0;   // initialize
                        $blockprice  = 0;
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_transaction->find('first', array('fields' => 'Order_transaction.id', 'conditions' => array('Order_transaction.reference_id' => $pin))));
                        
                        foreach ($block['items'] as $item) {
                
                            $orderId = $item['id'];
                            $refId   = $item['reference_id'];
                            $qty     = (int)$item['quantity'];
                
                            // ------------------------------------------
                            // FETCH ORIGINAL ORDERHISTORY
                            // ------------------------------------------
                            $original = $this->Order_orderhistory->find('first', [
                                'conditions' => [
                                    'Order_orderhistory.id' => $orderId,
                                    'Order_orderhistory.reference_id' => $refId,
                                    'Order_orderhistory.status !=' => 0
                                ]
                            ]);
                
                            if (empty($original)) {
                                throw new Exception("Original orderhistory not found: ID $orderId");
                            }
                
                            // prepare new row
                            $new = $original['Order_orderhistory'];
                            
                            $new['order_history_id'] = $new['id'];
                            unset($new['id']);
                            
                            $new['quantity'] = $qty;
                
                            // recalc
                            $new['total_tax']   = (($new['price'] * $qty) * $new['total_tax_percentage']) / 100;
                            $new['total_price'] = ($new['price'] * $qty);
                            
                            $new['split_reference_id'] = $pin;
                        
                            // SAVE split orderhistory
                            $this->Order_split_orderhistory->create();
                            if (!$this->Order_split_orderhistory->save($new)) {
                                throw new Exception("Failed saving Order_split_orderhistory");
                            }
                
                            // accumulate split totals
                            $blockprice += $new['price'];
                            $blockAmount += $new['price'] * $qty;
                            $blockTax    += $new['total_tax'];
                
                        } // end items loop
                
                        // =========================================================
                        // 2. SAVE SPLIT TRANSACTION FOR THIS BLOCK
                        // =========================================================
                
                        $tx = [];
                        $tx['split_reference_id'] = $pin;
                        
                        $tx['reference_id'] = $refId;
                        $tx['store_id']     = $location_id;
                        $tx['device_id']    = $device_id;
                        $tx['cashier_id']   = $cashierid;
                        $tx['waiter_id']    = $waiter_id;
                        $tx['waiter_name']  = $waiter_name;
                        $tx['name']         = $name;
                        $tx['phone']        = $phone;
                        $tx['address']      = $address;
                
                        $tx['table_number'] = $table_number;
                        
                        
                        $tx['price']        = round($blockAmount, 2);
                        $tx['total_tax']    = round($blockTax, 2);
                        // $tx['amount']       = round($blockAmount + $blockTax, 2);
                
                        $splitExactAmount = ($blockAmount + $blockTax);          // exact value
                        $splitRound2      = round($splitExactAmount, 2);         // 2 decimals
                        $splitFinalAmount = round($splitExactAmount);            // nearest integer
                        $splitRoundOff    = round($splitFinalAmount - $splitRound2, 2); // round diff
                        
                        $tx['amount']    = $splitFinalAmount;   // integer payable
                        $tx['round']     = $splitRoundOff;       // round-off value

                        $tx['is_split']     = 1;
                        $tx['createtime']   = $currenttime;
                        
                        $GOrder = sprintf("%08d", $ordernonewno);
                        $orderNumber = $series_id."".$series.date('Y').$GOrder;     
            
                        $tx['orderno']   = $orderNumber;
                        
                        $tx['createtime']   = $currenttime;
                        
                        $this->Order_split_transaction->create();
                        if (!$this->Order_split_transaction->save($tx)) {
                            throw new Exception("Failed saving split transaction");
                        }
                    
                        $ordernonewno++;
                    
                    } // end block loop
                
                    // =========================================================
                    // 3. SAVE MAIN / FINAL ORDER_TRANSACTION
                    // =========================================================
                    $datas['Order_transaction']=array(
                        'reference_id'=>$table_referenceid,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'store_id'=>$location_id,
                        'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                        'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                        'discount'=>round($orderss[0][0]['discount'],2),
                        'discount_items'=>$dish_type,
                        'amount'=>$finalamount,
                        'round'=>round($round_amount,2),
                        'name'=>$name,
                        'phone'=>$phone,
                        'address'=>$address,
                        'tokenno'=>$token,
                        'table_number'=>$table_number,
                        'pax'=>$pax,
                        'waiter_id'=>$waiter_id,
                        'waiter_name'=>$waiter_name,
                        'is_takeaway' => $is_takeaway,
                        'createtime'=>$currenttime,
                        'is_split' => $is_split,
                        'split_count' => $split_count,
                        'split_type' => 'item'
                    );
                
                    if (!$this->Order_transaction->save($datas['Order_transaction'])) {
                        throw new Exception("Failed to save final Order_transaction");
                    }
                
                    // =========================================================
                    // 4. UPDATE TABLES (ONLY IF EVERYTHING ABOVE SUCCESS)
                    // =========================================================
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 3 ,sync=0,local_sync=0
                        WHERE reference_id = '$table_referenceid' AND status != 0
                    ");
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 1,sync=0,local_sync=0 
                        WHERE reference_id IN ($refid) AND status != 0
                    ");
                
                    $this->Order_table_tracking->query("
                        UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0
                        WHERE merged_table_ref_id IN ($refid)
                    ");
                
                    // COMMIT ALL
                    $this->Order_transaction->commit();
                    
                    if($disc>=0){
                        if (!$this->bill_table_package_kds_discount($cashierid,$table_referenceid,$disc,$sc,$type,$dish_type)) {
                        
                            return json_encode([
                                'status'  => false,
                                'message' => "Main Discount not saved",
                            ]);
                        }
                        
                        //Split
                        $splittransactions = $this->Order_split_transaction->find('all', [
                            'fields' => [
                                'Order_split_transaction.*'
                            ],
                            'conditions' => [
                                'Order_split_transaction.reference_id' => $table_referenceid,
                                'Order_split_transaction.status !=' => 0
                            ]
                        ]);
                    
                        if (!empty($splittransactions)) {
                    
                            foreach ($splittransactions as $split) {
                                
                                $split_reference_id=$split['Order_split_transaction']['split_reference_id'];
                            
                                $this->split_bill_table_package_kds_discount($cashierid,$table_referenceid,$split_reference_id,$disc,$sc,$type,$dish_type);
                                
                            }
                        }
                    }
                    
                    return json_encode([
                        'status' => true,
                        'message' => 'Split saved and final transaction saved successfully'
                    ]);
                
                } catch (Exception $e) {
                
                    $this->Order_transaction->rollback();
                
                    return json_encode([
                        'status' => false,
                        'message' => $e->getMessage()
                    ]);
                }
            }
        
        return json_encode($response);
    }
    */
    
    public function split_bill_table_package_discount()
    {
        $response['status']= false;
        $response['message']= "fail";
        
        $cashierid = $_REQUEST['id'];
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id is Missing",
            );
            return json_encode($response);
        }
        $table_number = $_REQUEST['table_number'];
        if($table_number==''){
            $response =array(
                'status'=> false,
                'message'=> "Table Number is Missing",
            );
            return json_encode($response);
        }
        $table_referenceid = $_REQUEST['reference_id'];
        if($table_referenceid==''){
            $response =array(
                'status'=> false,
                'message'=> "Table refernce Id is Missing",
            );
            return json_encode($response);
        }
        
        $disc=$_REQUEST['discount'];
        $type = $_REQUEST['type'];
        $dish_type = $_REQUEST['kds'];
        $sc = $_REQUEST['service_charge'] ?? 0;
        
        if($disc==''){
            return json_encode([
                'status'=> false,
                'message'=> "Discount Missing",
            ]);
        }
        
        if($type==''){
            return json_encode([
                'status'=> false,
                'message'=> "Discount Type Missing",
            ]);
        }
        
        if($dish_type==''){
            return json_encode([
                'status'=> false,
                'message'=> "Dish Type Missing",
            ]);
        }
        
        $device_id='';
        if(isset($_REQUEST['device_id'])){
            $device_id=$_REQUEST['device_id'];
        }
        $name='';
        if(isset($_REQUEST['name'])){
            $name=$_REQUEST['name'];
        }
        $phone='';
        if(isset($_REQUEST['phone'])){
            $phone=$_REQUEST['phone'];
        }
        $address='';
        if(isset($_REQUEST['address'])){
            $address=$_REQUEST['address'];
        }
        $pax=1;
        if(isset($_REQUEST['pax'])){
            $pax=$_REQUEST['pax'];
        }
        
        if (!isset($_REQUEST['data'])) {
            $response = array(
                'status' => false,
                'message' => "data not found",
            );
            return json_encode($response);
        }
        
        $data = json_decode($_REQUEST['data'], true);
        
        // Check if JSON is valid
        if ($data === null) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json'
            ]);
        }
        
        // Validate required structure
        if (
            !isset($data['splits']) ||
            !is_array($data['splits']) ||
            count($data['splits']) == 0
        ) {
            return json_encode([
                'status' => false,
                'message' => 'invalid json structure: splits missing'
            ]);
        }
        
        foreach ($data['splits'] as $split) {
        
            // Check items key
            if (!isset($split['items']) || !is_array($split['items']) || count($split['items']) == 0) {
                return json_encode([
                    'status' => false,
                    'message' => 'invalid json structure: items missing'
                ]);
            }
        
            foreach ($split['items'] as $item) {
        
                if (
                    !isset($item['id']) ||
                    !isset($item['reference_id']) ||
                    !isset($item['quantity'])
                ) {
                    return json_encode([
                        'status' => false,
                        'message' => 'invalid json structure: item keys missing'
                    ]);
                }
            }
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        else{
            $location_id = $users['User']['location_id'];
        }
            
        $tablechk = $this->Order_table->find('first', array('conditions'=>array('Order_table.reference_id'=>$table_referenceid,'Order_table.number'=>$table_number,'Order_table.status'=>2)));
        if(empty($tablechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "Something went wrong for this table kindly check!!!",
            );
            return json_encode($response);
        }
        
        $orderQtyRes = $this->Order_orderhistory->query("
            SELECT id, quantity, product_name, product_id
            FROM order_orderhistories
            WHERE reference_id = '$table_referenceid'
              AND status != 0
        ");
        $originalQty = [];
        $originalName = [];

        foreach ($orderQtyRes as $row) {
            $itemId = $row['order_orderhistories']['id'];
            // $originalQty[$itemId] = (int)$row[0]['total_qty'];
            // $originalname[$itemId] = $row['order_orderhistories']['product_name'];
            $originalQty[$itemId] = (int)$row['order_orderhistories']['quantity'];
            $originalName[$itemId] = $row['order_orderhistories']['product_name'];

        }
        
        $splitQty = [];
        
        foreach ($data['splits'] as $split) {
            foreach ($split['items'] as $item) {
        
                $id = $item['id'];
                $qty = (int)$item['quantity'];
        
                if (!isset($splitQty[$id])) {
                    $splitQty[$id] = 0;
                }
        
                $splitQty[$id] += $qty;
            }
        }
        
        foreach ($originalQty as $itemId => $qtyFromOrder) {
        
            $qtyFromSplit = isset($splitQty[$itemId]) ? $splitQty[$itemId] : 0;
        
            if ($qtyFromSplit != $qtyFromOrder) {
                
                $itemName = isset($originalName[$itemId]) ? $originalName[$itemId] : 'Item #'.$itemId;

                return json_encode([
                    'status' => false,
                    'message' => "Invalid quantity for $itemName: Ordered $qtyFromOrder, Given $qtyFromSplit"
                ]);
            }
        }

        $waiter_id=$tablechk['Order_table']['waiter_id'];
        $waiter_name = $tablechk['Order_table']['waiter_name'];
        $pax = $tablechk['Order_table']['customer_pax'];
        $name    = trim($tablechk['Order_table']['customer_name']);
        $phone   = trim($tablechk['Order_table']['customer_phone']);
        $address = trim($tablechk['Order_table']['customer_address']);
        $is_takeaway = $tablechk['Order_table']['is_takeaway'];

        $customerchk = $this->Order_customers->find('first', [
            'conditions' => ['Order_customers.phone' => $phone,'Order_customers.status !=' => 0],
            'fields' => ['Order_customers.id'],
            'recursive' => -1
        ]);
    
        if (empty($customerchk)) {
            // Insert new customer
            $data = [
                'Order_customers' => [
                    'phone'   => $phone,
                    'name'    => $name,
                    'address' => $address
                ]
            ];
    
            if ($this->Order_customers->saveAll($data)) {
                
            } else {
                return json_encode([
                    'status' => false,
                    'message' => "Failed to save customer details."
                ]);
            }
        } else {
            // Customer already exists — optional: update their name/address if needed
            $this->Order_customers->id = $customerchk['Order_customers']['id'];
            $this->Order_customers->save([
                'name' => $name,
                'address' => $address
            ]);
    
        }
        
        $this->Order_table->updateAll(
            [
                'Order_table.waiter_id' => "'0'",
                'Order_table.waiter_name' => "''",
                'Order_table.customer_address' => "''",
                'Order_table.customer_phone' => "''",
                'Order_table.sync'              => 0,
                'Order_table.local_sync'        => 0
            ],
            ['Order_table.reference_id' => $table_referenceid]
        );
        
        $trxchck = $this->Order_transaction->find('first', array(
            'conditions' => array(
                'Order_transaction.reference_id' => $table_referenceid,
                'NOT' => array('Order_transaction.status' => array(3, 4, 0))
            )
        ));
        if(!empty($trxchck))
        {
            $response =array(
                'status'=> false,
                'message'=> "Reference Id already Exist",
            );
            return json_encode($response);
        }        
        
        $todayDate = date("Y-m-d");
        
        $refid = []; // T9-fix: no merged tables guard

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $table_referenceid,
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $refid[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        
        $refid = "'" . implode("','", $refid) . "'";
        
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            SET o.reference_id = '$table_referenceid',o.sync=0,o.local_sync=0
            WHERE o.reference_id IN ($refid)
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            SET t.reference_id = '$table_referenceid',t.sync=0,t.local_sync=0
            WHERE t.reference_id IN ($refid)
        ");
        
        //chk package value in table - item in ordergistory link quanti*package
        // Fetch all product_ids for the given reference_id
        // 1. Set package=1 for packaged items using JOIN (efficient)
        $this->Order_orderhistory->query("
            UPDATE order_orderhistories o
            JOIN catalog_package p ON o.product_id = p.main_product_id AND p.status = 1
            SET o.package = 1,o.sync=0,o.local_sync=0
            WHERE o.reference_id = '$table_referenceid' AND o.status != 0
        ");
        
        $this->Order_tax->query("
            UPDATE order_tax t
            JOIN catalog_package p ON t.product_id = p.main_product_id AND p.status = 1
            SET t.package = 1,t.sync=0,t.local_sync=0
            WHERE t.reference_id = '$table_referenceid' AND t.status = 1
        ");
        // 2. Get total packaged quantity
        $total_package = 0;
        $totalpackagechkorder = $this->Order_orderhistory->query("
            SELECT SUM(package) AS total_package
            FROM order_orderhistories 
            WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 1
        ");
        $packagechngchk=false;
        if (!empty($totalpackagechkorder[0][0]['total_package'])) {
            
            $total_package = isset($totalpackagechkorder[0][0]['total_package']) 
                ? $totalpackagechkorder[0][0]['total_package'] 
                : 0;
                // 3. Non-package items and discount percentage logic
                $discount_percentage = 0;
                $nonpackagechkorder = $this->Order_orderhistory->query("
                    SELECT product_id, SUM(quantity) as order_quantity
                    FROM order_orderhistories 
                    WHERE reference_id = '$table_referenceid' AND status != 0 AND package = 0
                    GROUP BY product_id
                ");
                $discount_pro_array = []; // initialize
                foreach ($nonpackagechkorder as $row) {
                    $orderproduct_id = $row['order_orderhistories']['product_id'];
                    $orderproduct_quantity = $row[0]['order_quantity'];
                    
                    // 4. Find linked package quantity for this non-package item
                    $linkpackagechk = $this->Catalog_package->query("
                        SELECT SUM(link_quantity) AS link_qty,link_product_id
                        FROM catalog_package
                        WHERE link_product_id = '$orderproduct_id' AND status = 1
                        AND main_product_id IN (
                            SELECT product_id 
                            FROM order_orderhistories 
                            WHERE reference_id = '$table_referenceid' AND package = 1 AND status != 0
                        )
                    ");
                    
                    $link_package_item_quantity = 0;
                    if (!empty($linkpackagechk[0][0]['link_qty'])) {
                        $link_package_item_quantity = $linkpackagechk[0][0]['link_qty'];
                    }
                    
                    // 5. Calculate discount
                    if ($orderproduct_quantity <= $link_package_item_quantity) {
                        $discount_percentage = 100;
                    } elseif ($link_package_item_quantity > 0) {
                        $discount_percentage = round(($link_package_item_quantity * 100) / $orderproduct_quantity, 2);
                    } else {
                        $discount_percentage = 0;
                    }
                    // print_r($discount_percentage);exit;
                
                    $orderdata = $this->ordercomputewithpackagediscount($table_referenceid, $cashierid,$orderproduct_id, $discount_percentage);
                    if($orderdata['status'])
                    {
                        $packagechngchk=true;
                    }
                }
            }

            //discount update in ordertax
            $orderss = $this->Order_orderhistory->query("SELECT sum(price) as price,sum(total_tax) as total_tax,sum(total_price) as total_price,sum(discount) as discount FROM `order_orderhistories` WHERE reference_id='$table_referenceid' and status!=0");
            if(!empty($orderss))
            {
                if($orderss[0][0]['total_price']<1){
                    $response =array(
                        'status'=> false,
                        'message'=> "There is no item to bill. Please Check..!",
                    );
                    return json_encode($response);
                }
                
                $todayDate = date("Y-m-d");
                $tdaytrx=$this->Order_transaction->query("SELECT COUNT(id) as tkn FROM `order_transactions` WHERE date(created)='$todayDate' and status=2");
                $token=$tdaytrx['0']['0']['tkn']+1;
                $currenttime=date("H:i:s");
                $updated_discount=0;
                $updated_tax=0;
                $updated_final_amount=0;
                if($packagechngchk){
                    $orderstaxdatas = $this->Order_tax->query("SELECT ot.product_id, SUM((ot.price * ot.quantity) * (ot.discount_percentage / 100)) AS discounted_total, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (IFNULL(ooh.tax_percent, 0) / 100)) AS total_tax, SUM(((ot.price * ot.quantity) * (ot.discount_percentage / 100)) * (1 + (IFNULL(ooh.tax_percent, 0) / 100))) AS final_amount FROM order_tax ot LEFT JOIN ( SELECT product_id, SUM(total_tax_percentage) AS tax_percent FROM order_orderhistories WHERE reference_id = '$table_referenceid' AND status = 1 GROUP BY product_id ) ooh ON ooh.product_id = ot.product_id WHERE ot.reference_id = '$table_referenceid' AND ot.package = 0 AND ot.status = 1");
                    if(!empty($orderstaxdatas))
                    {
                        $updated_discount=$orderstaxdatas[0][0]['discounted_total'];
                        $updated_tax=$orderstaxdatas[0][0]['total_tax'];
                        $updated_final_amount=$orderstaxdatas[0][0]['final_amount'];
                    }
                }
                $grand_total = $orderss[0][0]['total_price'] + $orderss[0][0]['total_tax'];
                $net_total = $grand_total - $orderss[0][0]['discount'] - $updated_final_amount;
                
                $finalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount);        // Rounded to nearest integer
                $roundfinalamount = round(($orderss[0][0]['total_price']+$orderss[0][0]['total_tax'])-$orderss[0][0]['discount']-$updated_final_amount,2); // Rounded to 2 decimal places
                
                $round_amount = $finalamount - $roundfinalamount;
                $split_count = count($data['splits']);
                
                $is_split=1;
                if($split_count==1){
                    $split_count=0;
                    $is_split=0;
                }
                
                $this->Order_transaction->begin();
                
                try {
                
                    // =========================================================
                    // 1. SAVE ALL SPLIT DETAILS (orderhistory + tax + split tx)
                    // =========================================================
                    
                    $series_id=sprintf("%02d", $cashierid);
                    $users=$this->User->find('first',array('conditions'=>array('id'=>$cashierid)));
                    $series=strtoupper(substr($users['User']['username'],0,2)); 

                    $ordertrx=$this->Order_transaction->query("SELECT orderno,split_count FROM `order_transactions` order by id desc limit 1");
                    
                    if($ordertrx[0]['order_transactions']['split_count']>1){
                     $last_split_count=$ordertrx[0]['order_transactions']['split_count']-1;
                    }else{
                     $last_split_count=0;
                    }
                     
                    $ordernewstring = substr($ordertrx[0]['order_transactions']['orderno'], -8) + $last_split_count;
                    $ordernonewno=$ordernewstring+1;
                    
                    foreach ($data['splits'] as $block) {
                
                        $refId = null;
                        $blockAmount = 0;   // initialize
                        $blockTax    = 0;   // initialize
                        $blockprice  = 0;
                        
                        do {
                            $pin = 'TX' . $cashierid . date('Y') . uniqid();
                            // $pin = uniqid();
                        } while ($this->Order_transaction->find('first', array('fields' => 'Order_transaction.id', 'conditions' => array('Order_transaction.reference_id' => $pin))));
                        
                        foreach ($block['items'] as $item) {
                
                            $orderId = $item['id'];
                            $refId   = $item['reference_id'];
                            $qty     = (int)$item['quantity'];
                
                            // ------------------------------------------
                            // FETCH ORIGINAL ORDERHISTORY
                            // ------------------------------------------
                            $original = $this->Order_orderhistory->find('first', [
                                'conditions' => [
                                    'Order_orderhistory.id' => $orderId,
                                    'Order_orderhistory.reference_id' => $refId,
                                    'Order_orderhistory.status !=' => 0
                                ]
                            ]);
                
                            if (empty($original)) {
                                throw new Exception("Original orderhistory not found: ID $orderId");
                            }
                
                            // prepare new row
                            $new = $original['Order_orderhistory'];
                            
                            $new['order_history_id'] = $new['id'];
                            unset($new['id']);
                            
                            $new['quantity'] = $qty;
                
                            // recalc
                            $new['total_tax']   = (($new['price'] * $qty) * $new['total_tax_percentage']) / 100;
                            $new['total_price'] = ($new['price'] * $qty);
                            
                            $new['split_reference_id'] = $pin;
                        
                            // SAVE split orderhistory
                            $this->Order_split_orderhistory->create();
                            if (!$this->Order_split_orderhistory->save($new)) {
                                throw new Exception("Failed saving Order_split_orderhistory");
                            }
                
                            // accumulate split totals
                            $blockprice += $new['price'];
                            $blockAmount += $new['price'] * $qty;
                            $blockTax    += $new['total_tax'];
                
                        } // end items loop
                
                        // =========================================================
                        // 2. SAVE SPLIT TRANSACTION FOR THIS BLOCK
                        // =========================================================
                
                        $tx = [];
                        $tx['split_reference_id'] = $pin;
                        
                        $tx['reference_id'] = $refId;
                        $tx['store_id']     = $location_id;
                        $tx['device_id']    = $device_id;
                        $tx['cashier_id']   = $cashierid;
                        $tx['waiter_id']    = $waiter_id;
                        $tx['waiter_name']  = $waiter_name;
                        $tx['name']         = $name;
                        $tx['phone']        = $phone;
                        $tx['address']      = $address;
                
                        $tx['table_number'] = $table_number;
                        
                        
                        $tx['price']        = round($blockAmount, 2);
                        $tx['total_tax']    = round($blockTax, 2);
                        // $tx['amount']       = round($blockAmount + $blockTax, 2);
                
                        $splitExactAmount = ($blockAmount + $blockTax);          // exact value
                        $splitRound2      = round($splitExactAmount, 2);         // 2 decimals
                        $splitFinalAmount = round($splitExactAmount);            // nearest integer
                        $splitRoundOff    = round($splitFinalAmount - $splitRound2, 2); // round diff
                        
                        $tx['amount']    = $splitFinalAmount;   // integer payable
                        $tx['round']     = $splitRoundOff;       // round-off value

                        $tx['is_split']     = 1;
                        $tx['createtime']   = $currenttime;
                        
                        $GOrder = sprintf("%08d", $ordernonewno);
                        $orderNumber = $series_id."".$series.date('Y').$GOrder;     
            
                        $tx['orderno']   = $orderNumber;
                        
                        $tx['createtime']   = $currenttime;
                        
                        $this->Order_split_transaction->create();
                        if (!$this->Order_split_transaction->save($tx)) {
                            throw new Exception("Failed saving split transaction");
                        }
                    
                        $ordernonewno++;
                    
                    } // end block loop
                
                    // =========================================================
                    // 3. SAVE MAIN / FINAL ORDER_TRANSACTION
                    // =========================================================
                    $datas['Order_transaction']=array(
                        'reference_id'=>$table_referenceid,
                        'device_id'=>$device_id,
                        'cashier_id'=>$cashierid,
                        'store_id'=>$location_id,
                        'price'=>round($orderss[0][0]['total_price']-$updated_discount,2),
                        'total_tax'=>round($orderss[0][0]['total_tax']-$updated_tax,2),
                        'discount'=>round($orderss[0][0]['discount'],2),
                        'discount_items'=>$dish_type,
                        'amount'=>$finalamount,
                        'round'=>round($round_amount,2),
                        'name'=>$name,
                        'phone'=>$phone,
                        'address'=>$address,
                        'tokenno'=>$token,
                        'table_number'=>$table_number,
                        'pax'=>$pax,
                        'waiter_id'=>$waiter_id,
                        'waiter_name'=>$waiter_name,
                        'is_takeaway' => $is_takeaway,
                        'createtime'=>$currenttime,
                        'is_split' => $is_split,
                        'split_count' => $split_count,
                        'split_type' => 'item'
                    );
                
                    if (!$this->Order_transaction->save($datas['Order_transaction'])) {
                        throw new Exception("Failed to save final Order_transaction");
                    }
                
                    // =========================================================
                    // 4. UPDATE TABLES (ONLY IF EVERYTHING ABOVE SUCCESS)
                    // =========================================================
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 3 ,sync=0,local_sync=0
                        WHERE reference_id = '$table_referenceid' AND status != 0
                    ");
                
                    $this->Order_table->query("
                        UPDATE order_tables SET status = 1,sync=0,local_sync=0 
                        WHERE reference_id IN ($refid) AND status != 0
                    ");
                
                    $this->Order_table_tracking->query("
                        UPDATE order_table_tracking SET status = 0,sync=0,local_sync=0
                        WHERE merged_table_ref_id IN ($refid)
                    ");
                
                    // COMMIT ALL
                    $this->Order_transaction->commit();
                    
                    if($disc>=0){
                        if (!$this->bill_table_package_kds_discount($cashierid,$table_referenceid,$disc,$sc,$type,$dish_type)) {
                        
                            return json_encode([
                                'status'  => false,
                                'message' => "Main Discount not saved",
                            ]);
                        }
                        
                        //Split
                        $splittransactions = $this->Order_split_transaction->find('all', [
                            'fields' => [
                                'Order_split_transaction.*'
                            ],
                            'conditions' => [
                                'Order_split_transaction.reference_id' => $table_referenceid,
                                'Order_split_transaction.status !=' => 0
                            ]
                        ]);
                    
                        if (!empty($splittransactions)) {
                    
                            foreach ($splittransactions as $split) {
                                
                                $split_reference_id=$split['Order_split_transaction']['split_reference_id'];
                            
                                $this->split_bill_table_package_kds_discount($cashierid,$table_referenceid,$split_reference_id,$disc,$sc,$type,$dish_type);
                                
                            }
                        }
                    }
                    
                    return json_encode([
                        'status' => true,
                        'message' => 'Split saved and final transaction saved successfully'
                    ]);
                
                } catch (Exception $e) {
                
                    $this->Order_transaction->rollback();
                
                    return json_encode([
                        'status' => false,
                        'message' => $e->getMessage()
                    ]);
                }
            }
        
        return json_encode($response);
    }
    
    /*
    public function split_bill_table_package_kds_discount($cashierid,$ref_id,$split_reference_id,$disc,$sc,$type,$dish_type)
    {
        $todayDate = date("Y-m-d");
    
        // if($dish_type==='all'){
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_split_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1
        //     ");
    
        //     if(!empty($kdss)){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        // }
        // else{
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_split_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1 
        //         AND dish_type=$dish_type
        //     ");
    
        //     if (!empty($kdss) && !empty($kdss[0][0]['kds'])){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        //     else{
        //         // return json_encode([
        //         //     'status'=> false,
        //         //     'message'=> "No kds found for this dish type",
        //         // ]);
        //         // print_r("No kds found for this dish type");
        //     }
        // }
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', [
                    'conditions'=>[
                        'Coupon.code'=>$disc,
                        'Coupon.expiry_date >='=>$todayDate,
                        'Coupon.status'=>1
                    ]
                ]);
    
                if(empty($coup)){
                    // return json_encode([
                    //     'status'=> false,
                    //     'message'=> "Coupon not found Or Coupon Expired",
                    // ]);
                    // print_r("1");
                }
    
                $disc=$coup['Coupon']['value'];
            }
            else{
                $disc=0;
            }
        }
    
        if($type==1){
            $disc=$disc;
        }
    
        if($type==2){
    
            if($dish_type==='all'){
                $subtotals = $this->Order_split_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_split_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
                ");
            }
            else{
                $subtotals = $this->Order_split_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_split_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
                    AND product_id in (SELECT id from catalog_product WHERE dish_type=$dish_type and status=1)
                ");
            }
    
            if($subtotals){
                $subtotal = $subtotals[0][0]['subtotal'];
    
                if($subtotal){
                    $disc = (($disc * 100) / $subtotal);
                }
                else{
                    return json_encode([
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    ]);
                }
            }
            else{
                return json_encode([
                    'status'=> false,
                    'message'=> "Bill Not Found",
                ]);
            }
        }
    
        if($disc > 99){
            return json_encode([
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            ]);
            // print_r("2");
        }
    
        $kdsarray = explode(",", $kds);
    
        // if($dish_type!='all'){
        //     $kdschk = $this->Pos_printer->find('first', [
        //         'conditions'=>['Pos_printer.kds'=>$kdsarray,'Pos_printer.status'=>1]
        //     ]);
        // };
       
        if($dish_type!='all'){
            $kdschk = $this->Order_split_orderhistory->find('first', [
                'conditions'=>[
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id,
                    'Order_split_orderhistory.status !='=>0,
                    'Order_split_orderhistory.dish_type'=> $dish_type
                ],
                'recursive' => -1
            ]);
        }
        else{
            $kdschk = $this->Order_split_orderhistory->find('first', [
                'conditions'=>[
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id,
                    'Order_split_orderhistory.status !='=>0
                ],
                'recursive' => -1
            ]);
        }
    
        if(empty($kdschk)){
            return json_encode([
                'status'=> false,
                'message'=> "No Item found for this Dish Type while applying discount.",
            ]);
        }
    
    
        $packagechk = $this->Order_split_orderhistory->find('first', [
            'conditions' => [
                'Order_split_orderhistory.reference_id'       => $ref_id,
                'Order_split_orderhistory.split_reference_id' => $split_reference_id,
                'Order_split_orderhistory.package'            => 1,
                'Order_split_orderhistory.status >'           => 0
            ],
            'recursive' => -1
        ]);

        if(!empty($packagechk)){
            return json_encode([
                'status'=> false,
                'message'=> "You cannot merge Discount with package.",
            ]);
        }
     
        if($disc>=0){
            $checkdiscount=$this->Order_split_orderhistory->find('first',[
                'conditions'=>[
                    'Order_split_orderhistory.discount > '=>0,
                    'Order_split_orderhistory.cashier_id'=>$cashierid,
                    'Order_split_orderhistory.status'=>2,
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id
                ],
                'recursive' => -1
            ]);
    
            if(!empty($checkdiscount)){
                return json_encode([
                    'status'=> false,
                    'message'=> "Discount cannot merge with item level discount"
                ]);
            }
        }
        else{
            return json_encode([
                'status'=> false,
                'message'=> "Please check discount value"
            ]);
        }
        
        if($dish_type==='all'){
            $orderdata=$this->split_ordercompute($ref_id,$split_reference_id,$cashierid,$sc,$disc);
        }else{
            $orderdata=$this->split_ordercomputewithkds($ref_id,$split_reference_id,$cashierid,$sc,$disc,$dish_type);
        }
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            // $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            $exactTotalAmount = (($totalprice + $totaltax + $totalservicechg) - $totaldiscount);

            $round2TotalAmount = round($exactTotalAmount, 2);   // 2 decimal value
            $finalTotalAmount  = round($exactTotalAmount);      // nearest integer
            $roundOffAmount    = round($finalTotalAmount - $round2TotalAmount, 2);
            
            $createtime = date('H:i:s');
    
            $this->Order_split_transaction->query("
                UPDATE order_split_transactions 
                SET 
                    price = '$totalprice',
                    total_tax='$totaltax',
                    servicecharge='$totalservicechg',
                    discount='$totaldiscount',
                    discount_type='$type',
                    amount='$finalTotalAmount',
                    round='$roundOffAmount',
                    createtime='$createtime',sync=0,local_sync=0
                WHERE reference_id = '$ref_id' and split_reference_id='$split_reference_id' and status!=0
            ");
            
            return json_encode([
                'status'=> true,
                'message'=> "Saved",
            ]);
        }
        else{
            return json_encode([
                'status'=> false,
                'message'=> "Not Saved",
            ]);
        }
    }
    */
    
    public function split_bill_table_package_kds_discount($cashierid,$ref_id,$split_reference_id,$disc,$sc,$type,$dish_type)
    {
        $todayDate = date("Y-m-d");
    
        // if($dish_type==='all'){
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_split_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1
        //     ");
    
        //     if(!empty($kdss)){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        // }
        // else{
        //     $kdss = $this->Catalog_product->query("
        //         SELECT GROUP_CONCAT(kds) as kds 
        //         FROM catalog_product 
        //         WHERE id IN (
        //             SELECT product_id 
        //             FROM order_split_orderhistories 
        //             WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
        //             GROUP BY kds
        //         ) 
        //         AND status=1 
        //         AND dish_type=$dish_type
        //     ");
    
        //     if (!empty($kdss) && !empty($kdss[0][0]['kds'])){
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        //     else{
        //         // return json_encode([
        //         //     'status'=> false,
        //         //     'message'=> "No kds found for this dish type",
        //         // ]);
        //         // print_r("No kds found for this dish type");
        //     }
        // }
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', [
                    'conditions'=>[
                        'Coupon.code'=>$disc,
                        'Coupon.expiry_date >='=>$todayDate,
                        'Coupon.status'=>1
                    ]
                ]);
    
                if(empty($coup)){
                    // return json_encode([
                    //     'status'=> false,
                    //     'message'=> "Coupon not found Or Coupon Expired",
                    // ]);
                    // print_r("1");
                }
    
                $disc=$coup['Coupon']['value'];
            }
            else{
                $disc=0;
            }
        }
    
        if($type==1){
            $disc=$disc;
        }
        
        /*
        if($type==2){
    
            if($dish_type==='all'){
                $subtotals = $this->Order_split_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_split_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
                ");
            }
            else{
                $subtotals = $this->Order_split_orderhistory->query("
                    SELECT SUM(total_price) as subtotal 
                    FROM order_split_orderhistories 
                    WHERE status!=0 AND reference_id='$ref_id' AND split_reference_id='$split_reference_id' 
                    AND dish_type=$dish_type
                ");
            }
    
            if($subtotals){
                $subtotal = $subtotals[0][0]['subtotal'];
    
                if($subtotal){
                    $disc = round((($disc * 100) / $subtotal),2);
                }
                else{
                    return json_encode([
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    ]);
                }
            }
            else{
                return json_encode([
                    'status'=> false,
                    'message'=> "Bill Not Found",
                ]);
            }
        }
                */
        
        if($type==2){
        
            // get FULL bill subtotal (not split subtotal)
            $fullsubtotal = $this->Order_split_orderhistory->query("
                SELECT SUM(total_price) as subtotal 
                FROM order_split_orderhistories 
                WHERE status!=0 AND reference_id='$ref_id'
            ");
        
            if(!empty($fullsubtotal[0][0]['subtotal'])){
                
                $billSubtotal = $fullsubtotal[0][0]['subtotal'];
        
                if($billSubtotal > 0){
                    // convert flat discount to percentage once
                    $disc = round((($disc * 100) / $billSubtotal),2);
                }else{
                    return json_encode([
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    ]);
                }
        
            }else{
                return json_encode([
                    'status'=> false,
                    'message'=> "Bill Not Found",
                ]);
            }
        }

        if($disc > 99){
            // return json_encode([
            //     'status'=> false,
            //     'message'=> "Discount is not more than 99%",
            // ]);
            // print_r("2");
        }
    
        $kdsarray = explode(",", $kds);
    
        if($dish_type!='all'){
            $kdschk = $this->Pos_printer->find('first', [
                'conditions'=>['Pos_printer.kds'=>$kdsarray,'Pos_printer.status'=>1]
            ]);
        };
       
        if($dish_type!='all'){
            $kdschk = $this->Order_split_orderhistory->find('first', [
                'conditions'=>[
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id,
                    'Order_split_orderhistory.dish_type'=>$dish_type,
                    'Order_split_orderhistory.status !='=>0
                ],
                'recursive' => -1
            ]);
        }
        else{
            $kdschk = $this->Order_split_orderhistory->find('first', [
                'conditions'=>[
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id,
                    'Order_split_orderhistory.status !='=>0
                ],
                'recursive' => -1
            ]);
        }
    
        if(empty($kdschk)){
            // return json_encode([
            //     'status'=> false,
            //     'message'=> "No Item found for this KDS while applying discount.",
            // ]);
        }
    
    
        $packagechk = $this->Order_split_orderhistory->find('first', [
            'conditions' => [
                'Order_split_orderhistory.reference_id'       => $ref_id,
                'Order_split_orderhistory.split_reference_id' => $split_reference_id,
                'Order_split_orderhistory.package'            => 1,
                'Order_split_orderhistory.status >'           => 0
            ],
            'recursive' => -1
        ]);

        if(!empty($packagechk)){
            // return json_encode([
            //     'status'=> false,
            //     'message'=> "You cannot merge Discount with package.",
            // ]);
            // print_r("5");
        }
     
        if($disc>=0){
            $checkdiscount=$this->Order_split_orderhistory->find('first',[
                'conditions'=>[
                    'Order_split_orderhistory.discount > '=>0,
                    'Order_split_orderhistory.cashier_id'=>$cashierid,
                    'Order_split_orderhistory.status'=>2,
                    'Order_split_orderhistory.reference_id'=>$ref_id,
                    'Order_split_orderhistory.split_reference_id'=>$split_reference_id
                ],
                'recursive' => -1
            ]);
    
            if(!empty($checkdiscount)){
                // return json_encode([
                //     'status'=> false,
                //     'message'=> "Discount cannot merge with item level discount"
                // ]);
                // print_r("6");
            }
        }
        else{
            // return json_encode([
            //     'status'=> false,
            //     'message'=> "Please check discount value"
            // ]);
            // print_r("7");
        }
        
        if($dish_type=='all'){
            $orderdata=$this->split_ordercompute($ref_id,$split_reference_id,$cashierid,$sc,$disc);
        }else{
            $orderdata=$this->split_ordercomputewithkds($ref_id,$split_reference_id,$cashierid,$sc,$disc,$dish_type);
        }
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            // $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            $exactTotalAmount = (($totalprice + $totaltax + $totalservicechg) - $totaldiscount);

            $round2TotalAmount = round($exactTotalAmount, 2);   // 2 decimal value
            $finalTotalAmount  = round($exactTotalAmount);      // nearest integer
            $roundOffAmount    = round($finalTotalAmount - $round2TotalAmount, 2);
            
            $createtime = date('H:i:s');
    
            $this->Order_split_transaction->query("
                UPDATE order_split_transactions 
                SET 
                    price = '$totalprice',
                    total_tax='$totaltax',
                    servicecharge='$totalservicechg',
                    discount='$totaldiscount',
                    discount_type='$type',
                    discount_items='$dish_type',
                    amount='$finalTotalAmount',
                    round='$roundOffAmount',
                    createtime='$createtime',sync=0,local_sync=0
                WHERE reference_id = '$ref_id' and split_reference_id='$split_reference_id' and status!=0
            ");
            
            // return json_encode([
            //     'status'=> true,
            //     'message'=> "Saved",
            // ]);
        }
        else{
            // return json_encode([
            //     'status'=> false,
            //     'message'=> "Not Saved",
            // ]);
        }
    }
    
    public function split_ordercompute($txnid=null,$split_reference_id=null,$user_id=null,$is_sc=1,$discount=0)
    {
        $response['status']=false;
        $totalservicechg=0;
        $totalprice=0;
        $totaltax1=0;
        $totaltax2=0;
        $totaldiscount=0;
        $sc=0;
        if($is_sc==1){
            $sc=servicecharge;
        }
        $this->Order_split_orderhistory->virtualFields = [];

        $discq="(((Order_split_orderhistory.total_price)-(Order_split_orderhistory.discount))*$discount/100)";
        $priceq="((Order_split_orderhistory.total_price)-(Order_split_orderhistory.discount))";
    
        $this->Order_split_orderhistory->virtualFields = array('tdisc'=>"SUM($discq)",'tservicechg'=>"SUM(($priceq-$discq)*($sc/100))",'tprice'=>"SUM($priceq)",'total_tax'=>"SUM(($priceq+(($priceq-$discq)*($sc/100))-$discq)*((Order_split_orderhistory.total_tax_percentage)/100))");  
        
        $orderhistories = $this->Order_split_orderhistory->find('first', [
            'conditions' => [
                'Order_split_orderhistory.reference_id'       => $txnid,
                'Order_split_orderhistory.split_reference_id' => $split_reference_id,
                'Order_split_orderhistory.status !='          => 0
            ],
            'fields' => [
                'tdisc',
                'Order_split_orderhistory.reference_id',
                'tprice',
                'total_tax',
                'tservicechg'
            ],
            'recursive' => -1
        ]);

        if(!empty($orderhistories['Order_split_orderhistory']['reference_id'])){
            $response['status']=true;
            $totalservicechg=round($orderhistories['Order_split_orderhistory']['tservicechg'],2);
            $totalprice=round($orderhistories['Order_split_orderhistory']['tprice'],2);
            $totaltax=round($orderhistories['Order_split_orderhistory']['total_tax'],2);
            $totaldiscount=round($orderhistories['Order_split_orderhistory']['tdisc'],2);
            
            $response['totalservicechg']=$totalservicechg;
            $response['totalprice']=$totalprice;
            $response['totaltax']=$totaltax;
            $response['totaldiscount']=$totaldiscount;
        }
        // print_r($response);exit;
        return $response;
    }
    
    public function split_ordercomputewithkds(
        $txnid = null,
        $split_reference_id = null,
        $user_id = null,
        $is_sc = 1,
        $discount = 0,
        $dish_type = 0
    ){
        $response = ['status' => false];
    
        if (empty($txnid) || empty($split_reference_id)) {
            return $response;
        }
    
        $sc  = ($is_sc == 1) ? servicecharge : 0;
        $kds = (int)$dish_type;
    
        // --------------------------------------------------
        // STEP 1 : FETCH ALL SPLIT ITEMS
        // --------------------------------------------------
        $items = $this->Order_split_orderhistory->find('all', [
            'conditions' => [
                'Order_split_orderhistory.reference_id'       => $txnid,
                'Order_split_orderhistory.split_reference_id' => $split_reference_id,
                'Order_split_orderhistory.status !='          => 0
            ],
            'fields' => [
                'id',
                'dish_type',
                'price',
                'quantity',
                'discount',
                'total_tax_percentage'
            ],
            'recursive' => -1
        ]);
    
        if (empty($items)) {
            return $response;
        }
    
        // --------------------------------------------------
        // STEP 2 : CALCULATE TOTALS (same as main function)
        // --------------------------------------------------
        $totalprice = 0;
        $totaldiscount = 0;
        $totalservicechg = 0;
        $totaltax = 0;
    
        foreach ($items as $row) {
    
            $item = $row['Order_split_orderhistory'];
    
            $basePrice = ($item['price'] * $item['quantity']) - $item['discount'];
    
            // discount only for matching dish_type
            $applyDiscount = ($item['dish_type'] == $kds);
    
            $itemDiscount = $applyDiscount
                ? ($basePrice * $discount) / 100
                : 0;
    
            $priceAfterDiscount = $basePrice - $itemDiscount;
    
            $serviceCharge = ($priceAfterDiscount * $sc) / 100;
    
            $taxableAmount = $priceAfterDiscount + $serviceCharge;
    
            $taxValue = ($taxableAmount * $item['total_tax_percentage']) / 100;
    
            $totalprice      += $basePrice;
            $totaldiscount   += $itemDiscount;
            $totalservicechg += $serviceCharge;
            $totaltax        += $taxValue;
        }
    
        // --------------------------------------------------
        // STEP 3 : RETURN TOTALS
        // --------------------------------------------------
        return [
            'status'          => true,
            'totalprice'      => round($totalprice, 2),
            'totaldiscount'   => round($totaldiscount, 2),
            'totalservicechg' => round($totalservicechg, 2),
            'totaltax'        => round($totaltax, 2)
        ];
    }

    
    public function bill_preview_with_discount()
    {
        $cashierid = $_REQUEST['id'];
        $ref_id=$_REQUEST['reference_id'];
        $sc = $_REQUEST['service_charge'];
        $disc=$_REQUEST['discount'];
        $type = $_REQUEST['type'];
        $dish_type = $_REQUEST['kds'];
        $discount_type_value=$disc;
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        if($disc==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Missing",
            );
            return json_encode($response);
        }
        
        if($type==''){
            $response =array(
                'status'=> false,
                'message'=> "Discount Type Missing",
            );
            return json_encode($response);
        }
        
        if($dish_type==''){
            $response =array(
                'status'=> false,
                'message'=> "Dish Type Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $todayDate = date("Y-m-d");
        
        $ref_id = [$ref_id]; // convert initial ref id to array
        
        $refid = []; // T9-fix: no merged tables guard

        $mergetablecheck = $this->Order_table_tracking->find('all', [
            'conditions' => [
                'Order_table_tracking.main_table_ref_id' => $ref_id[0],
                'Order_table_tracking.status' => 1,
                "DATE(Order_table_tracking.created) =" => $todayDate
            ]
        ]);
        if (!empty($mergetablecheck)) {
            foreach ($mergetablecheck as $merge) {
                $ref_id[] = $merge['Order_table_tracking']['merged_table_ref_id']; 
            }
        }
        $ref_in = "'" . implode("','", $ref_id) . "'";
        
        // if($dish_type=='all'){
        //     $kdss = $this->Catalog_product->query("SELECT GROUP_CONCAT(kds) as kds FROM `catalog_product` WHERE id IN (SELECT product_id FROM `order_orderhistories` WHERE status!=0 and reference_id IN ($ref_in) group BY kds) and status=1");
        //     if(!empty($kdss))
        //     {
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }
        // }else{
        //     $kdss = $this->Catalog_product->query("SELECT GROUP_CONCAT(kds) as kds FROM `catalog_product` WHERE id IN (SELECT product_id FROM `order_orderhistories` WHERE status!=0 and reference_id  IN ($ref_in) group BY kds) and status=1  and dish_type=$dish_type");
        //     if (!empty($kdss) && !empty($kdss[0][0]['kds']))
        //     {
        //         foreach($kdss as $kdslist){
        //             $kds=$kdslist[0]['kds'];
        //         }
        //     }else{
        //         $response =array(
        //             'status'=> false,
        //             'message'=> "No kds found for this dish type",
        //         );
        //         return json_encode($response);
        //     }
        // }
        
        if($type==0){
            if(!empty($disc)){
                $coup = $this->Coupon->find('first', array('conditions'=>array('Coupon.code'=>$disc,'Coupon.expiry_date >='=>$todayDate,'Coupon.status'=>1)));
                if(empty($coup))
                {
                    $response =array(
                        'status'=> false,
                        'message'=> "Coupon not found Or Coupon Expired",
                    );
                    return json_encode($response);
                }
                $disc=$coup['Coupon']['value'];
            }else{
                $disc=0;
            }
        }
        
        if($type==1){
            $disc=$disc;
        }
        
        if($type==2){
            if($dish_type=='all'){
                $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id IN ($ref_in)");
            }else{
                $subtotals = $this->Order_orderhistory->query("SELECT SUM(total_price) as subtotal FROM `order_orderhistories` WHERE status!=0 and reference_id IN ($ref_in) and dish_type=$dish_type");
            }
            
            if($subtotals){
                $subtotal=$subtotals[0][0]['subtotal'];
                if($subtotal){
                    $disc=round((($disc*100)/$subtotal),2);
                }else{
                    $response =array(
                        'status'=> false,
                        'message'=> "Bill Not Found",
                    );
                    return json_encode($response);
                }
            }else{
                $response =array(
                    'status'=> false,
                    'message'=> "Bill Not Found",
                );
                return json_encode($response);
            }
        }
        
        if($disc>99){
            $response =array(
                'status'=> false,
                'message'=> "Discount is not more than 99%",
            );
            return json_encode($response);
        }
        
        $kdsarray = explode(",", $kds);
        
        // if($dish_type!='all'){
        //     $kdschk = $this->Pos_printer->find('first', array('conditions'=>array('Pos_printer.kds'=>$kdsarray,'Pos_printer.status'=>1)));
        //     if(empty($kdschk))
        //     {
        //         $response =array(
        //             'status'=> false,
        //             'message'=> "KDS not found",
        //         );
        //         return json_encode($response);
        //     }
        // }
        
        if($dish_type!='all'){
            $kdschk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.dish_type'=>$dish_type,'Order_orderhistory.status !='=>0)));
        }else{
            $kdschk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.status !='=>0)));
        }
        if(empty($kdschk))
        {
            $response =array(
                'status'=> false,
                'message'=> "No Item found for this KDS.",
            );
            return json_encode($response);
        }
        
        $packagechk = $this->Order_orderhistory->find('first', array('conditions'=>array('Order_orderhistory.reference_id'=>$ref_id,'Order_orderhistory.package'=>1,'Order_orderhistory.status !='=>0)));
        if(!empty($packagechk))
        {
            $response =array(
                'status'=> false,
                'message'=> "You can not Merge Discount with package.",
            );
            return json_encode($response);
        }
        
        if($disc>=0){
            $checkdiscount=$this->Order_orderhistory->find('first',array('conditions'=>array('Order_orderhistory.discount > '=>0,'Order_orderhistory.cashier_id'=>$cashierid,'Order_orderhistory.status'=>2,'Order_orderhistory.reference_id'=>$ref_id)));
            if(!empty($checkdiscount)){
                $response['status']= false;
                $response['message']= "Discount can not merge with item level discount";
                return json_encode($response);     
            }
        }else{
            $response['status']= false;
            $response['message']= "please check discount value";
            return json_encode($response);  
        }
        
        if($dish_type=='all'){
            $orderdata=$this->ordercomputewithdiscounttemp($ref_id,$cashierid,$sc,$disc);
        }else{
            // $this->Order_tax->query("UPDATE order_tax SET discount_percentage='0' WHERE reference_id = '$ref_id'");
            $orderdata=$this->ordercomputewithkdstemp($ref_id,$cashierid,$sc,$disc,$dish_type);
        }
        
        if($orderdata['status'])
        {
            $totalservicechg=$orderdata['totalservicechg'];
            $totalprice=$orderdata['totalprice'];
            $totaltax=$orderdata['totaltax'];
            $totaldiscount=$orderdata['totaldiscount'];
            $totalamount=round((($totalprice+$totaltax+$totalservicechg)-$totaldiscount),2);
            
            //print_r($totalamount);exit;
            
            $orderitems=[];
            // $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,SUM(quantity) as quantity,price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id IN ($ref_in) and status!=0 group BY product_id");
            $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,quantity as quantity,price,total_tax as total_tax,total_tax_percentage as total_tax_percentage,total_price as total_price,discount as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id IN ($ref_in) and status!=0");
            
            if(!empty($orderss))
            {
                foreach($orderss as $orders){
                    if(!isset($orders['order_orderhistories']['remarks'])){
                        $orders['order_orderhistories']['remarks']='';
                    }
                    
                    $taxesitems=[];
                    $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$orders['order_orderhistories']['product_id'],'Catalog_product_tax.status'=>1)));
                    foreach($taxess as $tax){
                        $taxesitems[]=array(
                            'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                            'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                            'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                        );
                    }
                    
                    $orderitems[]=array(
                        'id' => $orders['order_orderhistories']['id'],
                        'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                        'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                        'group_id' =>  $orders['order_orderhistories']['group_id'],
                        'category' =>  $orders['order_orderhistories']['category'],
                        'category_name' =>  $orders['order_orderhistories']['category_name'],
                        'kds' =>  $orders['order_orderhistories']['kds'],
                        'product_id' =>  $orders['order_orderhistories']['product_id'],
                        'product_name' =>  $orders['order_orderhistories']['product_name'],
                        'quantity' =>  $orders['order_orderhistories']['quantity'],
                        'price' =>  $orders['order_orderhistories']['price'],
                        'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                        'total_price' =>  $orders['order_orderhistories']['total_price'],
                        'discount' =>  $orders['order_orderhistories']['discount'],
                        'table_number' =>  $orders['order_orderhistories']['table_number'],
                        'remarks' =>  $orders['order_orderhistories']['remarks'],
                        'status' =>  $orders['order_orderhistories']['status'],
                        'created' =>  $orders['order_orderhistories']['created'],
                        'taxes'=>$taxesitems
                    );
                }
            }
            $tablenomb=0;
            $tableno=$this->Order_table->query("SELECT GROUP_CONCAT(number) as tbale FROM `order_tables` WHERE status!=0 and reference_id IN ($ref_in)");
            if($tableno){
               $tablenomb =$tableno[0][0]['tbale'];
            }
            
            $finalamount=0;
            $transactionitems=[];
            $createtime = date('H:i:s');
            $transactionitems[]=array(
                'id' => '',
                'reference_id' =>  $ref_in,
                'orderno' =>  '',
                'device_id' =>  '',
                'cashier_id' =>  $cashierid,
                'table_number'        => (string) $tablenomb,
                'price'               => (string) number_format($totalprice, 2), // optional 2 decimals
                'total_tax'           => (string) round($totaltax, 2),
                'servicecharge'       => (string) $totalservicechg,
                'discount'            => (string) $totaldiscount,
                'discount_percentage' => (string) $disc,
                'delivery_charge'     => '0',
                'packing_charge'      => '0',
                'amount'              => (string) round($totalamount, 2),
                'round'               => '0',
                'name' =>  '',
                'phone' =>  '',
                'address' => '',
                'remarks' =>  '',
                'status' =>  '',
                'tokenno' =>  '',
                'createtime' =>  $createtime,
                'created' =>  ''
            );
            
            $paymentitems=[];
            
            $taxitems=[];
            $taxess=$orderdata['taxes'];
            foreach($taxess as $tax){
                $taxitems[]=array(
                    'tax_id' => $tax['tax_id'],
                    'tax_name' =>  $tax['tax_name'],
                    'tax_percentage' =>  $tax['tax_percentage'],
                    'tax_value' =>  number_format($tax['tax_value'],1)
                );
            }
                
            $amount_diff=0;
            
            $cashier_name='';
            $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
            if($cashname){
               $cashier_name =$cashname[0]['users']['name'];
            }
            // print_r($cashname);exit;
            
            $printeritems=[];
            $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
            if(!empty($printerss))
            {
                foreach($printerss as $printers){
                    // print_r($tax);exit;
                    
                    $printeritems[]=array(
                        'id' => $printers['pos_printers']['id'],
                        'store_id' =>  $printers['pos_printers']['store_id'],
                        'name' =>  $printers['pos_printers']['name'],
                        'kds' =>  $printers['pos_printers']['kds'],
                        'ip' =>  $printers['pos_printers']['ip'],
                        'status' =>  $printers['pos_printers']['status']
                    );
                }
            }
            
            
            $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>(string) round($totalamount, 2)
            );
            
            return json_encode($response);
        }else{
            $response =array(
                'status'=> false,
                'message'=> "No data found",
            );
            return json_encode($response);
        }
    }
    
    public function ordercomputewithkdstemp($txnid = null, $user_id = null, $is_sc = 1, $discount = 0, $dish = 0)
    {
        $response = ['status' => false];
    
        if (empty($txnid)) {
            return $response;
        }
    
        $sc = ($is_sc == 1) ? servicecharge : 0;
        $kds = (int)$dish; // dish type to filter discount
    
        // STEP 1: FETCH ALL ORDER ITEMS
        $items = $this->Order_orderhistory->find('all', [
            'conditions' => [
                'Order_orderhistory.reference_id' => $txnid,
                'Order_orderhistory.status !=' => 0
            ],
            'fields' => [
                'Order_orderhistory.id',
                'Order_orderhistory.product_id',
                'Order_orderhistory.dish_type',
                'Order_orderhistory.price',
                'Order_orderhistory.quantity',
                'Order_orderhistory.discount',
                'Order_orderhistory.total_tax_percentage'
            ],
            'recursive' => -1
        ]);
    
        if (empty($items)) return $response;
    
        // STEP 2: CALCULATE TOTALS
        $totalprice = $totaldiscount = $totalservicechg = $totaltax = 0;
    
        foreach ($items as $row) {
            $item = $row['Order_orderhistory'];
    
            $basePrice = ($item['price'] * $item['quantity']) - $item['discount'];
            $applyDiscount = ($item['dish_type'] == $kds);
            $itemDiscount = $applyDiscount ? ($basePrice * $discount) / 100 : 0;
    
            $priceAfterDiscount = $basePrice - $itemDiscount;
            $serviceCharge = ($priceAfterDiscount * $sc) / 100;
            $taxableAmount = $priceAfterDiscount + $serviceCharge;
            $taxValue = ($taxableAmount * $item['total_tax_percentage']) / 100;
    
            $totalprice += $basePrice;
            $totaldiscount += $itemDiscount;
            $totalservicechg += $serviceCharge;
            $totaltax += $taxValue;
        }
    
        // STEP 3: UPDATE ORDER TAX (RESET + APPLY)
        $taxRows = $this->Order_tax->find('all', [
            'conditions' => [
                'Order_tax.reference_id' => $txnid,
                'Order_tax.status !=' => 0
            ],
            'fields' => [
                'Order_tax.id',
                'Order_tax.orderhistory_id',
                'Order_tax.tax_percentage',
                'Order_tax.quantity'
            ],
            'recursive' => -1
        ]);
    
        // Build a lookup map
        $itemMap = [];
        foreach ($items as $itemRow) {
            $itemMap[$itemRow['Order_orderhistory']['id']] = $itemRow['Order_orderhistory'];
        }
    
        foreach ($taxRows as $row) {
            $tax = $row['Order_tax'];
    
            if (!isset($itemMap[$tax['orderhistory_id']])) continue;
    
            $item = $itemMap[$tax['orderhistory_id']];
    
            $basePrice = ($item['price'] * $tax['quantity']) - $item['discount'];
    
            // Use the item’s dish_type to determine discount
            $applyDiscount = ($item['dish_type'] == $kds);
            $itemDiscount = $applyDiscount ? ($basePrice * $discount) / 100 : 0;
    
            $priceAfterDiscount = $basePrice - $itemDiscount;
            $serviceCharge = ($priceAfterDiscount * $sc) / 100;
            $taxablePrice = round($priceAfterDiscount + $serviceCharge, 2);
            $taxValue = round(($taxablePrice * $tax['tax_percentage']) / 100, 2);
            $discountPercent = $applyDiscount ? (float)$discount : 0.0;
    
            // // Update tax row
            // try {
            //     $this->Order_tax->updateAll(
            //         [
            //             'taxable_price' => (float)$taxablePrice,
            //             'tax_value' => (float)$taxValue,
            //             'discount_percentage' => $discountPercent,
            //             'dish_type' => (int)$item['dish_type'], // crucial: copy dish_type from item
            //             'sync' => 0,
            //             'local_sync' => 0
            //         ],
            //         ['id' => (int)$tax['id']]
            //     );
            // } catch (Exception $e) {
            //     $this->trackUser($txnid, $user_id, 'order_tax_update_error', [
            //         'tax_id' => $tax['id'],
            //         'error' => $e->getMessage()
            //     ]);
            // }
        }
    
        // STEP 4: RETURN TOTALS
        return [
            'status' => true,
            'totalprice' => round($totalprice, 2),
            'totaldiscount' => round($totaldiscount, 2),
            'totalservicechg' => round($totalservicechg, 2),
            'totaltax' => round($totaltax, 2)
        ];
    }
//     public function split_table_unbill()
//     {
//         $cashierid = $_REQUEST['id'];
//         $ref_id = $_REQUEST['reference_id'];
        
//         $response = array();
//         if($cashierid==''){
//             $response =array(
//                 'status'=> false,
//                 'message'=> "User Id Missing",
//             );
//             return json_encode($response);
//         }
        
//         if($ref_id==''){
//             $response =array(
//                 'status'=> false,
//                 'message'=> "Reference id Missing",
//             );
//             return json_encode($response);
//         }
        
//         $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
//         if(empty($users))
//         {
//             $response =array(
//                 'status'=> false,
//                 'message'=> "User not found",
//             );
//             return json_encode($response);
//         }
        
//         $txnchk = $this->Order_transaction->find('first', array('conditions'=>array('Order_transaction.reference_id'=>$ref_id)));
//         if(empty($txnchk))
//         {   
//             $response= array('status'=> false,
//                 'message'=> "No Transaction found"
//             );
//             return json_encode($response);
//         }else{
//             $tableid=$txnchk['Order_transaction']['table_number'];
            
//             $tables=$this->Order_table->find('first',array('conditions'=>array('Order_table.number'=>$tableid,'Order_table.reference_id'=>$ref_id,'Order_table.status !='=>0)));
// //          print_r($tables);exit;;
            
//             $orderdata=$this->ordercompute($ref_id,$cashierid,0,0);
            
//             // $this->Order_transaction->id=$txnchk['Order_transaction']['id'];
//             // // if($this->Order_transaction->delete()){
//             // $update = [
//             //     'Order_transaction' => [
//             //         'reference_id' =>$ref_id,
//             //         'status' => 0
//             //     ]
//             // ];
            
//             $updateData = [
//                 'Order_transaction.status' => 0
//             ];
            
//             $updated = $this->Order_transaction->updateAll(
//                 $updateData,
//                 ['Order_transaction.reference_id' => $ref_id]
//             );
            
//             if ($updated) {
                
//                 // $paymupdateData = [
//                 //     'Order_payment.status' => 0
//                 // ];
                
//                 // $paymentupdated = $this->Order_payment->updateAll(
//                 //     $paymupdateData,
//                 //     ['Order_payment.reference_id' => $ref_id]
//                 // );
                
//                 $splitupdateData = [
//                     'Order_split_transaction.status' => 0
//                 ];
                
//                 $splitupdated = $this->Order_split_transaction->updateAll(
//                     $splitupdateData,
//                     ['Order_split_transaction.reference_id' => $ref_id]
//                 );
                
//                 $splitorderupdateData = [
//                     'Order_split_orderhistory.status' => 0
//                 ];
                
//                 $splitorderupdated = $this->Order_split_orderhistory->updateAll(
//                     $splitorderupdateData,
//                     ['Order_split_orderhistory.reference_id' => $ref_id]
//                 );
                
//                 $splitorderpayupdateData = [
//                     'Order_split_payment.status' => 0
//                 ];
                
//                 $splitorderpayupdated = $this->Order_split_payment->updateAll(
//                     $splitorderpayupdateData,
//                     ['Order_split_payment.reference_id' => $ref_id]
//                 );
                
//                 if ($tables) {
//                     $this->Order_table->id = $tables['Order_table']['id'];
//                     $this->Order_table->saveField('status', '2');
//                 }
            
//                 $response = [
//                     'status' => true,
//                     'message' => "Bill updated"
//                 ];
//                 return json_encode($response);
            
//             } else {
            
//                 $response = [
//                     'status' => false,
//                     'message' => "Bill not updated"
//                 ];
//                 return json_encode($response);
//             }
//         }
//     }

    public function split_table_unbill()
    {
        $this->autoRender = false;
    
        $cashierid = $_REQUEST['id'];
        $ref_id = $_REQUEST['reference_id'];
        
        /* -------------------------
           VALIDATION
        ------------------------- */
    
        if (empty($cashierid)) {
            return json_encode([
                'status' => false,
                'message' => 'User Id Missing'
            ]);
        }
    
        if (empty($ref_id)) {
            return json_encode([
                'status' => false,
                'message' => 'Reference id Missing'
            ]);
        }
    
        /* -------------------------
           USER CHECK
        ------------------------- */
    
        $user = $this->User->find('first', [
            'conditions' => [
                'User.id' => $cashierid,
                'User.status' => 1
            ]
        ]);
    
        if (empty($user)) {
            return json_encode([
                'status' => false,
                'message' => 'User not found'
            ]);
        }
    
        /* -------------------------
           TRANSACTION CHECK
        ------------------------- */
    
        $txn = $this->Order_transaction->find('first', [
            'conditions' => ['Order_transaction.reference_id' => $ref_id,'Order_transaction.status !=' => 0]
        ]);
    
        if (empty($txn)) {
            return json_encode([
                'status' => false,
                'message' => 'No Transaction found'
            ]);
        }
    
        $tableid = $txn['Order_transaction']['table_number'];
    
        $table = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.number' => $tableid,
                'Order_table.reference_id' => $ref_id,
                'Order_table.status !=' => 0
            ]
        ]);
    
        /* -------------------------
           COMPUTE (your logic)
        ------------------------- */
    
        $this->ordercompute($ref_id, $cashierid, 0, 0);
    
        /* -------------------------
           DB TRANSACTION START
        ------------------------- */
    
        $ds = $this->Order_transaction->getDataSource();
        $ds->begin();
    
        try {
    
            /* ---- main transaction ---- */
            $this->Order_transaction->updateAll(
                [
                    'Order_transaction.status' => 0,
                    'Order_transaction.sync' => 0,
                    'Order_transaction.local_sync' => 0
                ],
                ['Order_transaction.reference_id' => $ref_id]
            );
    
            /* ---- split tables ---- */
            $this->Order_split_transaction->updateAll(
                [
                    'Order_split_transaction.status' => 0,
                    'Order_split_transaction.sync' => 0,
                    'Order_split_transaction.local_sync' => 0
                ],
                ['Order_split_transaction.reference_id' => $ref_id]
            );
    
            $this->Order_split_orderhistory->updateAll(
                [
                    'Order_split_orderhistory.status' => 0,
                    'Order_split_orderhistory.sync' => 0,
                    'Order_split_orderhistory.local_sync' => 0
                ],
                ['Order_split_orderhistory.reference_id' => $ref_id]
            );
    
            $this->Order_split_payment->updateAll(
                [
                    'Order_split_payment.status' => 0,
                    'Order_split_payment.sync' => 0,
                    'Order_split_payment.local_sync' => 0
                ],
                ['Order_split_payment.reference_id' => $ref_id]
            );
    
            /* ---- table status ---- */
            if (!empty($table['Order_table']['id'])) {
                $this->Order_table->updateAll(
                    [
                        'Order_table.status' => 2,
                        'Order_table.sync' => 0,
                        'Order_table.local_sync' => 0
                    ],
                    ['Order_table.id' => $table['Order_table']['id']]
                );
            }
    
            $ds->commit();
    
            return json_encode([
                'status' => true,
                'message' => 'Bill updated'
            ]);
    
        } catch (Exception $e) {
    
            $ds->rollback();
    
            return json_encode([
                'status' => false,
                'message' => 'Failed to update bill'
            ]);
        }
    }

    
    public function split_transaction_history()
    {
        $this->autoRender = false;
    
        $cashierid = $_REQUEST['id'] ?? '';
        $startdate = $_REQUEST['from'] ?? date("Y-m-d");
        $enddate   = $_REQUEST['to'] ?? date("Y-m-d");
        
        // build shift-based datetime
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        if ($cashierid == '') {
            return json_encode([
                'status'  => false,
                'message' => 'User Id Missing'
            ]);
        }
    
        $users = $this->User->find('first', [
            'conditions' => [
                'User.id'     => $cashierid,
                'User.status' => 1
            ]
        ]);
    
        if (empty($users)) {
            return json_encode([
                'status'  => false,
                'message' => 'Cashier not found'
            ]);
        }
    
        $transactionitems = [];
    
        /* ===================== SPLIT TRANSACTIONS ===================== */
    
        $splittransactions = $this->Order_split_transaction->find('all', [
            'conditions' => [
                'status'     => 2,
                'created BETWEEN ? AND ?' => [
                    $startDatetime,
                    $endDatetime
                ]
            ],
            'order' => ['Order_split_transaction.id' => 'DESC']
        ]);
    
        foreach ($splittransactions as $orders) {
    
            $ost = $orders['Order_split_transaction'];
    
            $reference_id       = $ost['reference_id'];
            $split_reference_id = $ost['split_reference_id'];
            $store_id           = $ost['store_id'];
    
            /* Discount Percentage */
            $discount_percentage = "0";
            $discper = $this->Order_tax->query("
                SELECT discount_percentage 
                FROM order_tax 
                WHERE reference_id = '$reference_id'
                  AND status != 0 
                  AND discount_percentage != 0
                LIMIT 1
            ");
    
            if (!empty($discper)) {
                $discount_percentage = number_format(
                    $discper[0]['order_tax']['discount_percentage'], 2
                );
            }
    
            /* Payment Mode */
            $payment_mode = '';
            $pay_mode = $this->Order_split_payment->query("
                SELECT GROUP_CONCAT(type_value) AS payment
                FROM order_split_payments
                WHERE reference_id = '$reference_id'
                  AND split_reference_id = '$split_reference_id'
                  AND store_id = '$store_id'
                  AND status = 2
            ");
            if (!empty($pay_mode)) {
                $payment_mode = $pay_mode[0][0]['payment'];
            }
    
            /* Split Order Items */
            $orderitems = [];
            $orderss = $this->Order_split_orderhistory->query("
                SELECT *,
                       SUM(quantity) AS quantity,
                       SUM(total_tax) AS total_tax,
                       SUM(total_price) AS total_price,
                       SUM(discount) AS discount
                FROM order_split_orderhistories
                WHERE reference_id = '$reference_id'
                  AND split_reference_id = '$split_reference_id'
                  AND store_id = '$store_id'
                  AND status != 0
                GROUP BY product_id
            ");
    
            foreach ($orderss as $items) {
    
                if (!isset($items['order_split_orderhistories']['remarks'])) {
                    $items['order_split_orderhistories']['remarks'] = '';
                }
    
                $oi = $items['order_split_orderhistories'];
    
                $orderitems[] = [
                    'id'            => $oi['id'],
                    'reference_id'  => $oi['reference_id'],
                    'cashier_id'    => $oi['cashier_id'],
                    'group_id'      => $oi['group_id'],
                    'category'      => $oi['category'],
                    'category_name' => $oi['category_name'],
                    'kds'           => $oi['kds'],
                    'product_id'    => $oi['product_id'],
                    'product_name'  => $oi['product_name'],
                    'quantity'      => $items[0]['quantity'],
                    'price'         => $oi['price'],
                    'total_tax'     => $items[0]['total_tax'],
                    'total_price'   => $items[0]['total_price'],
                    'discount'      => $items[0]['discount'],
                    'table_number'  => $oi['table_number'],
                    'remarks'       => $oi['remarks'] ?? '',
                    'status'        => $oi['status'],
                    'created'       => $oi['created']
                ];
            }
    
            $transactionitems[] = [
                'id'                    => $ost['id'],
                'reference_id'          => $reference_id,
                'split_reference_id'    => $split_reference_id,
                'orderno'               => $ost['orderno'],
                'device_id'             => $ost['device_id'],
                'cashier_id'            => $ost['cashier_id'],
                'table_number'          => $ost['table_number'],
                'price'                 => $ost['price'],
                'total_tax'             => $ost['total_tax'],
                'servicecharge'         => $ost['servicecharge'],
                'discount'              => $ost['discount'],
                'discount_percentage'   => $discount_percentage,
                'discount_type'         => $ost['discount_type'],
                'discount_type_value'   => $ost['discount_type_value'],
                'delivery_charge'       => $ost['delivery_charge'],
                'packing_charge'        => $ost['packing_charge'],
                'amount'                => $ost['amount'],
                'round'                 => $ost['round'],
                'name'                  => $ost['name'],
                'phone'                 => $ost['phone'],
                'address'               => $ost['address'],
                'remarks'               => $ost['remarks'] ?? '',
                'status'                => $ost['status'],
                'tokenno'               => $ost['tokenno'],
                'createtime'            => $ost['createtime'],
                'created'               => $ost['created'],
                'payment_mode'          => $payment_mode,
                'items'                 => $orderitems
            ];
        }
    
        /* ===================== NORMAL TRANSACTIONS ===================== */
    
        $transactions = $this->Order_transaction->find('all', [
            'conditions' => [
                'status'     => 2,
                'is_split'     => 0,
                'created BETWEEN ? AND ?' => [
                    $startDatetime,
                    $endDatetime
                ]
            ],
            'order' => ['Order_transaction.id' => 'DESC']
        ]);
    
        foreach ($transactions as $orders) {
    
            $ot = $orders['Order_transaction'];
            $reference_id = $ot['reference_id'];
            $store_id     = $ot['store_id'];
    
            /* Discount Percentage */
            $discount_percentage = "0";
            $discper = $this->Order_tax->query("
                SELECT discount_percentage 
                FROM order_tax 
                WHERE reference_id = '$reference_id'
                  AND status != 0
                  AND discount_percentage != 0
                LIMIT 1
            ");
            if (!empty($discper)) {
                $discount_percentage = number_format(
                    $discper[0]['order_tax']['discount_percentage'], 2
                );
            }
    
            /* Payment Mode */
            $payment_mode = '';
            $pay_mode = $this->Order_payment->query("
                SELECT GROUP_CONCAT(type_value) AS payment
                FROM order_payments
                WHERE reference_id = '$reference_id'
                  AND store_id = '$store_id'
                  AND status = 2
            ");
            if (!empty($pay_mode)) {
                $payment_mode = $pay_mode[0][0]['payment'];
            }
    
            /* Normal Order Items */
            $orderitems = [];
            $orderss = $this->Order_orderhistory->query("
                SELECT *,
                       SUM(quantity) AS quantity,
                       SUM(total_tax) AS total_tax,
                       SUM(total_price) AS total_price,
                       SUM(discount) AS discount
                FROM order_orderhistories
                WHERE reference_id = '$reference_id'
                  AND store_id = '$store_id'
                  AND status != 0
                GROUP BY product_id
            ");
    
            foreach ($orderss as $items) {
    
                if (!isset($items['order_orderhistories']['remarks'])) {
                    $items['order_orderhistories']['remarks'] = '';
                }
    
                $oi = $items['order_orderhistories'];
    
                $orderitems[] = [
                    'id'            => $oi['id'],
                    'reference_id'  => $oi['reference_id'],
                    'cashier_id'    => $oi['cashier_id'],
                    'group_id'      => $oi['group_id'],
                    'category'      => $oi['category'],
                    'category_name' => $oi['category_name'],
                    'kds'           => $oi['kds'],
                    'product_id'    => $oi['product_id'],
                    'product_name'  => $oi['product_name'],
                    'quantity'      => $items[0]['quantity'],
                    'price'         => $oi['price'],
                    'total_tax'     => $items[0]['total_tax'],
                    'total_price'   => $items[0]['total_price'],
                    'discount'      => $items[0]['discount'],
                    'table_number'  => $oi['table_number'],
                    'remarks'       => $oi['remarks'] ?? '',
                    'status'        => $oi['status'],
                    'created'       => $oi['created']
                ];
            }
    
            $transactionitems[] = [
                'id'                    => $ot['id'],
                'reference_id'          => $reference_id,
                'split_reference_id'    => 0,
                'orderno'               => $ot['orderno'],
                'device_id'             => $ot['device_id'],
                'cashier_id'            => $ot['cashier_id'],
                'table_number'          => $ot['table_number'],
                'price'                 => $ot['price'],
                'total_tax'             => $ot['total_tax'],
                'servicecharge'         => $ot['servicecharge'],
                'discount'              => $ot['discount'],
                'discount_percentage'   => $discount_percentage,
                'discount_type'         => $ot['discount_type'],
                'discount_type_value'   => $ot['discount_type_value'],
                'delivery_charge'       => $ot['delivery_charge'],
                'packing_charge'        => $ot['packing_charge'],
                'amount'                => $ot['amount'],
                'round'                 => $ot['round'],
                'name'                  => $ot['name'],
                'phone'                 => $ot['phone'],
                'address'               => $ot['address'],
                'remarks'               => $ot['remarks'] ?? '',
                'status'                => $ot['status'],
                'tokenno'               => $ot['tokenno'],
                'createtime'            => $ot['createtime'],
                'created'               => $ot['created'],
                'payment_mode'          => $payment_mode,
                'items'                 => $orderitems
            ];
        }
    
        /* ===================== SORT BY LAST NUMERIC PART OF ORDERNO ===================== */
        usort($transactionitems, function ($a, $b) {
        
            preg_match('/(\d+)$/', $a['orderno'], $ma);
            preg_match('/(\d+)$/', $b['orderno'], $mb);
        
            $numA = isset($ma[1]) ? (int)$ma[1] : 0;
            $numB = isset($mb[1]) ? (int)$mb[1] : 0;
        
            return $numB <=> $numA; // DESC
        });

        /* ===================== CASHIER NAME ===================== */
        $cashier_name = '';
        $cashname = $this->User->query("SELECT name FROM users WHERE id = '$cashierid'");
        if (!empty($cashname)) {
            $cashier_name = $cashname[0]['users']['name'];
        }
    
        return json_encode([
            'status'       => true,
            'message'      => 'success',
            'cashier_name' => $cashier_name,
            'transactions' => $transactionitems
        ]);
    }
    
    public function split_transaction_history_old()
    {
        $cashierid = $_REQUEST['id'];
        
        $startdate = date("Y-m-d");
        $enddate = date("Y-m-d");
            
        if(isset($_REQUEST['from'])){
            $startdate = $_REQUEST['from'];
        }
        if(isset($_REQUEST['to'])){
            $enddate = $_REQUEST['to'];
        }
        
        // Shift-based datetime range
        $startDatetime = $startdate . ' ' . shiftstart;
        $endDatetime   = date('Y-m-d', strtotime($enddate . ' +1 day')) . ' ' . shiftend;

        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "Cashier not found",
            );
            return json_encode($response);
        }
        
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('cashier_id'=>$cashierid,'status'=>2,'created BETWEEN ? AND ?' => array($startDatetime,$endDatetime)),'order' => array('Order_transaction.id' => 'DESC')));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                $store_id=$orders['Order_transaction']['store_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status!=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=number_format($discper[0]['order_tax']['discount_percentage'],2);
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                $payment_mode='';
                $pay_mode = $this->Order_payment->query("SELECT GROUP_CONCAT(type_value) as payment FROM `order_payments` WHERE reference_id='$reference_id' and store_id='$store_id' and status=2");
                if(!empty($pay_mode))
                {
                    $payment_mode=$pay_mode[0][0]['payment'];
                }
                
                $orderitems=[];
                $orderss = $this->Order_orderhistory->query("SELECT id,reference_id,group_id,cashier_id,category,category_name,kds,product_id,product_name,SUM(quantity) as quantity,price,sum(total_tax) as total_tax,sum(total_tax_percentage) as total_tax_percentage,sum(total_price) as total_price,SUM(discount) as discount,table_number,remarks,device_id,status,created FROM `order_orderhistories` WHERE reference_id='$reference_id' and store_id='$store_id' and status!=0 group BY product_id");
                if(!empty($orderss))
                {
                    foreach($orderss as $items){
                        if(!isset($items['order_orderhistories']['remarks'])){
                            $items['order_orderhistories']['remarks']='';
                        }
                        $orderitems[]=array(
                            'id' => $items['order_orderhistories']['id'],
                            'reference_id' =>  $items['order_orderhistories']['reference_id'],
                            'cashier_id' =>  $items['order_orderhistories']['cashier_id'],
                            'group_id' =>  $items['order_orderhistories']['group_id'],
                            'category' =>  $items['order_orderhistories']['category'],
                            'category_name' =>  $items['order_orderhistories']['category_name'],
                            'kds' =>  $items['order_orderhistories']['kds'],
                            'product_id' =>  $items['order_orderhistories']['product_id'],
                            'product_name' =>  $items['order_orderhistories']['product_name'],
                            'quantity' =>  $items[0]['quantity'],
                            'price' =>  $items['order_orderhistories']['price'],
                            'total_tax' =>  $items[0]['total_tax'],
                            'total_price' =>  $items[0]['total_price'],
                            'discount' =>  $items[0]['discount'],
                            'table_number' =>  $items['order_orderhistories']['table_number'],
                            'remarks' =>  $items['order_orderhistories']['remarks'] ?? '',
                            'status' =>  $items['order_orderhistories']['status'],
                            'created' =>  $items['order_orderhistories']['created']
                        );
                    }
                }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'] ?? '',
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'created' =>  $orders['Order_transaction']['created'],
                    'payment_mode' =>$payment_mode??'',
                    'items' =>$orderitems
                );
            }
        }
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'transactions'=>$transactionitems
            );
        return json_encode($response);
    }
    
    
    public function split_payment_status_update()
    {
        $this->autoRender = false;
    
        $cashierid    = ($_REQUEST['id'] ?? 0);
        $main_pay_id  = ($_REQUEST['main_pay_id'] ?? 0);
        $split_pay_id = ($_REQUEST['split_pay_id'] ?? 0);
    
        if (!$cashierid) {
            return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        }
    
        if (!$main_pay_id) {
            return json_encode(['status' => false, 'message' => 'Main Payment ID is missing']);
        }
    
        // ---------------------------
        // Validate User
        // ---------------------------
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive' => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
        
        // ---------------------------
        // Validate Main Payment
        // ---------------------------
        $mainPay = $this->Order_payment->find('first', [
            'conditions' => [
                'Order_payment.id' => $main_pay_id,
                'Order_payment.status !=' => 0
            ],
            'recursive' => -1
        ]);
    
        if (empty($mainPay)) {
            return json_encode(['status' => false, 'message' => 'Main payment not found']);
        }
    
        // ---------------------------
        // Split Payment Update (ONLY if ID > 0)
        // ---------------------------
        if ($split_pay_id > 0) {
    
            $split_update = $this->Order_split_payment->updateAll(
                [
                    'Order_split_payment.status'     => 0,
                    'Order_split_payment.sync'       => 0,
                    'Order_split_payment.local_sync' => 0
                ],
                [
                    'Order_split_payment.id' => $split_pay_id,
                    'Order_split_payment.status !=' => 0
                ]
            );
    
            if (!$split_update || $this->Order_split_payment->getAffectedRows() == 0) {
                return json_encode([
                    'status' => false,
                    'message' => 'Split payment update failed or already updated'
                ]);
            }
        }
    
        // ---------------------------
        // Main Payment Update
        // ---------------------------
        $main_update = $this->Order_payment->updateAll(
            [
                'Order_payment.status'     => 0,
                'Order_payment.sync'       => 0,
                'Order_payment.local_sync' => 0
            ],
            [
                'Order_payment.id' => $main_pay_id,
                'Order_payment.status !=' => 0
            ]
        );
    
        if (!$main_update || $this->Order_payment->getAffectedRows() == 0) {
            return json_encode([
                'status' => false,
                'message' => 'Main payment update failed or already updated'
            ]);
        }
    
        return json_encode([
            'status' => true,
            'message' => 'Payment status updated successfully'
        ]);
    }

    public function void_reprint_data()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        $group_id = $_REQUEST['order_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        if($group_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Group Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $orderitems=[];
        
        $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and id='$group_id' and status=0 ");
        if(!empty($orderss))
        {
            foreach($orderss as $orders){
                $product_id=$orders['order_orderhistories']['product_id'];
                $order_id=$orders['order_orderhistories']['id'];
                $selected_modifiers=[];
                $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status=0");
                foreach($orders_modifiers as $orders_modifier){
                    $modifiers=$orders_modifier['order_modifier'];
                    $modifier_group_id=$modifiers['modifier_group_id'];
                    $modifier_group_name=$modifiers['modifier_group_name'];
                    $modifier_id=$modifiers['modifier_id'];
                    $modifier_name=$modifiers['modifier_name'];
                    $modifier_price=$modifiers['modifier_price'];
                    
                    $selected_modifiers[]=array(
                        'modifier_group_id' => $modifier_group_id,
                        'modifier_group_name' => $modifier_group_name,
                        'modifier_id' => $modifier_id,
                        'modifier_name' => $modifier_name,
                        'modifier_price' => $modifier_price,
                    );
                }
                
                if(!isset($orders['order_orderhistories']['remarks'])){
                    $orders['order_orderhistories']['remarks']='';
                }
                $orderitems[]=array(
                    'id' => $orders['order_orderhistories']['id'],
                    'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                    'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                    'group_id' =>  $orders['order_orderhistories']['group_id'],
                    'category' =>  $orders['order_orderhistories']['category'],
                    'category_name' =>  $orders['order_orderhistories']['category_name'],
                    'kds' =>  $orders['order_orderhistories']['kds'],
                    'product_id' =>  $orders['order_orderhistories']['product_id'],
                    'product_name' =>  $orders['order_orderhistories']['product_name'],
                    'quantity' =>  $orders['order_orderhistories']['quantity'],
                    'price' =>  $orders['order_orderhistories']['price'],
                    'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                    'total_price' =>  $orders['order_orderhistories']['total_price'],
                    'discount' =>  $orders['order_orderhistories']['discount'],
                    'table_number' =>  $orders['order_orderhistories']['table_number'],
                    'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                    'remarks' =>  $orders['order_orderhistories']['remarks'],
                    'selected_modifiers' => $selected_modifiers,
                    'status' =>  $orders['order_orderhistories']['status'],
                    'created' =>  $orders['order_orderhistories']['created']
                );
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status'=>0)));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=$discper[0]['order_tax']['discount_percentage'];
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'pax' =>  $orders['Order_transaction']['pax'],
                    'created' =>  $orders['Order_transaction']['created']
                );
            }
        }
        
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status'=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                if($printers['pos_printers']['name']=='Bar'){
                    $name = $printers['pos_printers']['name'];
                    $ip = $printers['pos_printers']['ip'];
                }else{
                    $name = 'expo';
                    $ip='192.168.1.240';
                }
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $name,
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $ip,
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }
    
    public function refresh_data()
    {
        $cashierid = $_REQUEST['id'];
        $response = array();
        
        $response =array(
            'status'=> false,
            'message'=> "Not required",
        );
        return json_encode($response);
        
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "Cashier Id Missing",
            );
            return json_encode($response);
        }
        
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        
        $catitem=[];
        $locations = $this->User_location->query("
            SELECT location_id,id,location_name
            FROM `user_locations` 
            WHERE user_id=$cashierid AND status=1
        ");
        $all_locations=[];
        $item=[];
        foreach($locations as $location){
            $location_ids = $location['user_locations']['location_id'];
            
            $branchcategoreis = $this->Catalog_category_branches->find('all', array(
                'conditions' => array(
                    'Catalog_category_branches.location_id' => $location_ids,
                    'Catalog_category_branches.status' => 1
                )
            ));
        
            if(!empty($branchcategoreis)){
                foreach($branchcategoreis as $bracnhcategorei){
                    $branchcat_id=$bracnhcategorei['Catalog_category_branches']['category_id'];
                    $subitem=[];
                    
                    $categoreis = $this->Catalog_category->find('all', array('conditions'=>array('Catalog_category.status'=>1,'id'=>$branchcat_id)));
                    foreach($categoreis as $categorei){
                        $cat_id=$categorei['Catalog_category']['id'];
                    
                        if($categorei['Catalog_category']['is_subcategory']){
                            $subcats = $this->Catalog_subcategory->find('all', array('conditions'=>array('Catalog_subcategory.cat_id'=>$cat_id,'status'=>1)));
                            foreach($subcats as $subcat){
                                
                                $subitem[]=array(
                                    'id' => $subcat['Catalog_subcategory']['id'],
                                    'name' =>  $subcat['Catalog_subcategory']['name'],
                                    'image'=>'',
                                    'created' =>  $subcat['Catalog_subcategory']['created']
                                );
                                
                                $branchproducts = $this->Catalog_product_branches->find('all', array('conditions'=>array('Catalog_product_branches.location_id' => $location_ids,'Catalog_product_branches.status'=>1)));
                                if(!empty($branchproducts))
                                {
                                    foreach($branchproducts as $branchproduct){
                                        $branchproduct_id=$branchproduct['Catalog_product_branches']['product_id'];
                                    
                                        $products = $this->Catalog_product->find('all', array('conditions'=>array('id'=>$branchproduct_id,'status'=>1,'subcat_id'=>$subcat['Catalog_subcategory']['id'])));
                                        if(!empty($products))
                                        {
                                            foreach($products as $product){
                                                $taxesitems=[];
                                                $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                                                foreach($taxess as $tax){
                                                    $taxesitems[]=array(
                                                        'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                                        'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                                        'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                                    );
                                                }
                                                
                                                $groupmodifier_items = [];
                                                
                                                $modifierss = $this->Inventory_linking->find('all', [
                                                    'conditions' => [
                                                        'Inventory_linking.parent_id' => $product['Catalog_product']['id'],
                                                        'Inventory_linking.parent_type' => 'Product',
                                                        'Inventory_linking.component_type' => 'Modifier_group',
                                                        'Inventory_linking.status' => 1
                                                    ],
                                                    'joins' => [
                                                        [
                                                            'table' => 'catalog_modifier_group',
                                                            'alias' => 'Catalog_modifier_group',
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'Catalog_modifier_group.id = Inventory_linking.component_id',
                                                                'Catalog_modifier_group.status' => 1
                                                            ]
                                                        ],
                                                        [
                                                            'table' => 'inventory_linking',
                                                            'alias' => 'IL2', // Second-level linking
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'IL2.parent_id = Catalog_modifier_group.id',
                                                                'IL2.parent_type' => 'Modifier_group',
                                                                'IL2.component_type' => 'Modifier',
                                                                'IL2.status' => 1
                                                            ]
                                                        ],
                                                        [
                                                            'table' => 'catalog_modifier',
                                                            'alias' => 'Catalog_modifier',
                                                            'type' => 'LEFT',
                                                            'conditions' => [
                                                                'Catalog_modifier.id = IL2.component_id',
                                                                'Catalog_modifier.status' => 1
                                                            ]
                                                        ]
                                                    ],
                                                    'fields' => [
                                                        'Inventory_linking.id',
                                                        'Inventory_linking.component_id',
                                                        'Inventory_linking.component_name',
                                                        'Inventory_linking.created',
                                                
                                                        'Catalog_modifier_group.id',
                                                        'Catalog_modifier_group.name',
                                                        'Catalog_modifier_group.description',
                                                        'Catalog_modifier_group.group_type',
                                                        'Catalog_modifier_group.sort_order',
                                                        'Catalog_modifier_group.is_default',
                                                        'Catalog_modifier_group.min',
                                                        'Catalog_modifier_group.max',
                                                
                                                        'IL2.id',
                                                        'IL2.component_id',
                                                        'IL2.component_name',
                                                
                                                        'Catalog_modifier.id',
                                                        'Catalog_modifier.name',
                                                        'Catalog_modifier.description',
                                                        'Catalog_modifier.food_type',
                                                        'Catalog_modifier.sort_order',
                                                        'Catalog_modifier.price',
                                                        'Catalog_modifier.weight'
                                                    ],
                                                    'recursive' => -1
                                                ]);
                
                                                $groupMap = [];
                                                
                                                foreach ($modifierss as $mod_item) {
                                                    $groupId = $mod_item['Inventory_linking']['component_id'];
                                                
                                                    // Initialize group if not already present
                                                    if (!isset($groupMap[$groupId])) {
                                                        $groupMap[$groupId] = [
                                                            'id' => $mod_item['Inventory_linking']['id'],
                                                            'modifier_group_id' => $groupId,
                                                            'modifier_group_name' => $mod_item['Inventory_linking']['component_name'],
                                                            'group_type' => $mod_item['Catalog_modifier_group']['group_type'],
                                                            'sort_order' => $mod_item['Catalog_modifier_group']['sort_order'],
                                                            'is_default' => $mod_item['Catalog_modifier_group']['is_default'],
                                                            'min' => $mod_item['Catalog_modifier_group']['min'],
                                                            'max' => $mod_item['Catalog_modifier_group']['max'],
                                                            'description' => $mod_item['Catalog_modifier_group']['description'],
                                                            'created' => $mod_item['Inventory_linking']['created'],
                                                            'modifiers' => []
                                                        ];
                                                    }
                                                
                                                    // Only push modifier if exists
                                                    if (!empty($mod_item['Catalog_modifier']['id'])) {
                                                        // $foodType = $mod_item['Catalog_modifier']['food_type'] == 1 ? 'Non-Veg' : 'Veg';
                                                
                                                        $modifierData = [
                                                            'id' => $mod_item['Catalog_modifier']['id'],
                                                            'name' => $mod_item['Catalog_modifier']['name'],
                                                            'modifier_name' => $mod_item['IL2']['component_name'],
                                                            'food_type' => $mod_item['Catalog_modifier']['food_type'],
                                                            'sort_order' => $mod_item['Catalog_modifier']['sort_order'],
                                                            'price' => $mod_item['Catalog_modifier']['price'],
                                                            'weight' => $mod_item['Catalog_modifier']['weight'],
                                                            'description' => $mod_item['Catalog_modifier']['description'],
                                                        ];
                                                
                                                        $groupMap[$groupId]['modifiers'][] = $modifierData;
                                                    }
                                                }
                                                // Final group array
                                                $groupmodifier_items = array_values($groupMap);
                                            
                                                if($product['Catalog_product']['image']){
                                                    $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                                                }else{
                                                    $imgpth=''; 
                                                }        
                                                // print_r($imgpth);exit;
                                                
                                                $product_id=$product['Catalog_product']['id'];
                                                $todayDate = date("Y-m-d");
                                                
                                                $is_offer='0';
                                                $offer_id='';
                                                $offer_name='';
                                                $offer_type='';
                                                $start_date='';
                                                $start_time='';
                                                $end_date='';
                                                $end_time='';
                                                
                                                $offers = $this->Offer->query("SELECT *
                                                    FROM pos_offers
                                                    WHERE status = 1
                                                      AND sku_id = $product_id
                                                      AND start_date <= '$todayDate'
                                                      AND end_date >= '$todayDate' order by id desc LIMIT 1 ");
                                                      
                                                if($offers[0]['pos_offers']['offer_id']){
                                                    $is_offer='1';
                                                    $offer_id=$offers[0]['pos_offers']['offer_id'];
                                                    $offer_name=$offers[0]['pos_offers']['name'];
                                                    $offer_type=$offers[0]['pos_offers']['offer_type'];
                                                    $start_date=$offers[0]['pos_offers']['start_date'];
                                                    $start_time=$offers[0]['pos_offers']['start_time'];
                                                    $end_date=$offers[0]['pos_offers']['end_date'];
                                                    $end_time=$offers[0]['pos_offers']['end_time'];
                                                }
                                                
                                                $item[]=array(
                                                    'id' => $product['Catalog_product']['id'],
                                                    'name' =>  $product['Catalog_product']['name'],
                                                    'cat_id' =>  $product['Catalog_product']['subcat_id'],
                                                    'cat_name' =>  $product['Catalog_product']['subcat_name'],
                                                    'description' => $product['Catalog_product']['description'],
                                                    'food_type' =>  $product['Catalog_product']['food_type'],
                                                    'sort_order' =>  $product['Catalog_product']['sort_order'],
                                                    'recommended' =>  $product['Catalog_product']['recommended'],
                                                    'variation' =>  $product['Catalog_product']['variation'],
                                                    'price' => $branchproduct['Catalog_product_branches']['price'],
                                                    'kds' => $product['Catalog_product']['kds'],
                                                    'markup_price' =>  $product['Catalog_product']['markup_price'],
                                                    'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                                    'weight' =>  $product['Catalog_product']['weight'],
                                                    'serves_people' =>  $product['Catalog_product']['serves_people'],
                                                    'type' =>  $product['Catalog_product']['type'],
                                                    'image' => $imgpth,
                                                    'taxes'=>$taxesitems,
                                                    'modifier_group'=>$groupmodifier_items,
                                                    'status' =>  $product['Catalog_product']['status'],
                                                    'created' =>  $product['Catalog_product']['created'],
                                                    'store_id' => $location_ids,
                                                    'is_offer' =>  $is_offer,
                                                    'offer_id' =>  $offer_id ?? '',
                                                    'offer_name' =>  $offer_name ?? '',
                                                    'offer_type' =>  $offer_type ?? '',
                                                    'start_date' =>  $start_date ?? '',
                                                    'start_time' =>  $start_time ?? '',
                                                    'end_date' =>  $end_date ?? '',
                                                    'end_time' =>  $end_time ?? ''
                                                );
                                            }
                                        }
                                    }
                                }
                            }
                            $catitem[]=array(
                                'id' => $categorei['Catalog_category']['id'],
                                'name' =>  $categorei['Catalog_category']['name'],
                                'is_subcategory' =>  $categorei['Catalog_category']['is_subcategory'],
                                'type' =>  $categorei['Catalog_category']['type'],
                                'subcategory'=>$subitem,
                                'image'=>'',
                                'created' =>  $categorei['Catalog_category']['created'],
                                'store_id' => $location_ids
                            );
                        }else{
                 
                            $catitem[]=array(
                                'id' => $categorei['Catalog_category']['id'],
                                'name' =>  $categorei['Catalog_category']['name'],
                                'is_subcategory' =>  $categorei['Catalog_category']['is_subcategory'],
                                'type' =>  $categorei['Catalog_category']['type'],
                                'subcategory'=>$subitem,
                                'image'=>'',
                                'created' =>  $categorei['Catalog_category']['created'],
                                'store_id' => $location_ids
                            );
                            
                            $branchproducts = $this->Catalog_product_branches->find('all', array('conditions'=>array('Catalog_product_branches.location_id' => $location_ids,'Catalog_product_branches.status'=>1)));
                            if(!empty($branchproducts))
                            {
                                foreach($branchproducts as $branchproduct){
                                    $branchproduct_id=$branchproduct['Catalog_product_branches']['product_id'];
                            
                                    $products = $this->Catalog_product->find('all', array('conditions'=>array('Catalog_product.id'=>$branchproduct_id,'Catalog_product.status'=>1,'Catalog_product.cat_id'=>$cat_id)));
                                    if(!empty($products))
                                    {
                                        foreach($products as $product){
                                            $taxesitems=[];
                                            $taxess = $this->Catalog_product_tax->find('all', array('conditions'=>array('Catalog_product_tax.product_id'=>$product['Catalog_product']['id'],'Catalog_product_tax.status'=>1)));
                                            foreach($taxess as $tax){
                                                $taxesitems[]=array(
                                                    'tax_id' => $tax['Catalog_product_tax']['tax_id'],
                                                    'tax_name' =>  $tax['Catalog_product_tax']['tax_name'],
                                                    'tax_percentage' =>  $tax['Catalog_product_tax']['tax_percentage']
                                                );
                                            }
                                        
                                        
                                            $groupmodifier_items = [];
                                            
                                            $modifierss = $this->Inventory_linking->find('all', [
                                                'conditions' => [
                                                    'Inventory_linking.parent_id' => $product['Catalog_product']['id'],
                                                    'Inventory_linking.parent_type' => 'Product',
                                                    'Inventory_linking.component_type' => 'Modifier_group',
                                                    'Inventory_linking.status' => 1
                                                ],
                                                'joins' => [
                                                    [
                                                        'table' => 'catalog_modifier_group',
                                                        'alias' => 'Catalog_modifier_group',
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'Catalog_modifier_group.id = Inventory_linking.component_id',
                                                            'Catalog_modifier_group.status' => 1
                                                        ]
                                                    ],
                                                    [
                                                        'table' => 'inventory_linking',
                                                        'alias' => 'IL2', // Second-level linking
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'IL2.parent_id = Catalog_modifier_group.id',
                                                            'IL2.parent_type' => 'Modifier_group',
                                                            'IL2.component_type' => 'Modifier',
                                                            'IL2.status' => 1
                                                        ]
                                                    ],
                                                    [
                                                        'table' => 'catalog_modifier',
                                                        'alias' => 'Catalog_modifier',
                                                        'type' => 'LEFT',
                                                        'conditions' => [
                                                            'Catalog_modifier.id = IL2.component_id',
                                                            'Catalog_modifier.status' => 1
                                                        ]
                                                    ]
                                                ],
                                                'fields' => [
                                                    'Inventory_linking.id',
                                                    'Inventory_linking.component_id',
                                                    'Inventory_linking.component_name',
                                                    'Inventory_linking.created',
                                            
                                                    'Catalog_modifier_group.id',
                                                    'Catalog_modifier_group.name',
                                                    'Catalog_modifier_group.description',
                                                    'Catalog_modifier_group.group_type',
                                                    'Catalog_modifier_group.sort_order',
                                                    'Catalog_modifier_group.is_default',
                                                    'Catalog_modifier_group.min',
                                                    'Catalog_modifier_group.max',
                                            
                                                    'IL2.id',
                                                    'IL2.component_id',
                                                    'IL2.component_name',
                                            
                                                    'Catalog_modifier.id',
                                                    'Catalog_modifier.name',
                                                    'Catalog_modifier.description',
                                                    'Catalog_modifier.food_type',
                                                    'Catalog_modifier.sort_order',
                                                    'Catalog_modifier.price',
                                                    'Catalog_modifier.weight'
                                                ],
                                                'recursive' => -1
                                            ]);
                                            
                                            $groupMap = [];
                                            
                                            foreach ($modifierss as $mod_item) {
                                                $groupId = $mod_item['Inventory_linking']['component_id'];
                                                
                                                // Initialize group if not already present
                                                if (!isset($groupMap[$groupId])) {
                                                    $groupMap[$groupId] = [
                                                        'id' => $mod_item['Inventory_linking']['id'],
                                                        'modifier_group_id' => $groupId,
                                                        'modifier_group_name' => $mod_item['Inventory_linking']['component_name'],
                                                        'group_type' => $mod_item['Catalog_modifier_group']['group_type'],
                                                        'sort_order' => $mod_item['Catalog_modifier_group']['sort_order'],
                                                        'is_default' => $mod_item['Catalog_modifier_group']['is_default'],
                                                        'description' => $mod_item['Catalog_modifier_group']['description'],
                                                        'min' => $mod_item['Catalog_modifier_group']['min'],
                                                        'max' => $mod_item['Catalog_modifier_group']['max'],
                                                        'created' => $mod_item['Inventory_linking']['created'],
                                                        'modifiers' => []
                                                    ];
                                                }
                                            
                                                // Only push modifier if exists
                                                if (!empty($mod_item['Catalog_modifier']['id'])) {
                                                    $foodType = $mod_item['Catalog_modifier']['food_type'] == 1 ? 'Non-Veg' : 'Veg';
                                            
                                                    $modifierData = [
                                                        'id' => $mod_item['Catalog_modifier']['id'],
                                                        'name' => $mod_item['Catalog_modifier']['name'],
                                                        'modifier_name' => $mod_item['IL2']['component_name'],
                                                        'food_type' => $mod_item['Catalog_modifier']['food_type'],
                                                        'sort_order' => $mod_item['Catalog_modifier']['sort_order'],
                                                        'price' => $mod_item['Catalog_modifier']['price'],
                                                        'weight' => $mod_item['Catalog_modifier']['weight'],
                                                        'description' => $mod_item['Catalog_modifier']['description'],
                                                    ];
                                            
                                                    $groupMap[$groupId]['modifiers'][] = $modifierData;
                                                }
                                            }
                                            
                                            // Final group array
                                            $groupmodifier_items = array_values($groupMap);
                
                                            
                                            if($product['Catalog_product']['image']){
                                                $imgpth=Router::url('/', true) . DS . 'uploads' . DS . 'product_images' . DS . $product['Catalog_product']['image'];
                                            }else{
                                                $imgpth=''; 
                                            } 
                                            
                                            $product_id=$product['Catalog_product']['id'];
                                            $todayDate = date("Y-m-d");
                                            
                                            $is_offer='0';
                                            $offer_id='';
                                            $offer_name='';
                                            $offer_type='';
                                            $start_date='';
                                            $start_time='';
                                            $end_date='';
                                            $end_time='';
                                            
                                            $offers = $this->Offer->query("SELECT *
                                                FROM pos_offers
                                                WHERE status = 1
                                                  AND sku_id = $product_id
                                                  AND start_date <= '$todayDate'
                                                  AND end_date >= '$todayDate' order by id desc LIMIT 1 ");
                                                  
                                            if($offers[0]['pos_offers']['offer_id']){
                                                $is_offer='1';
                                                $offer_id=$offers[0]['pos_offers']['offer_id'];
                                                $offer_name=$offers[0]['pos_offers']['name'];
                                                $offer_type=$offers[0]['pos_offers']['offer_type'];
                                                $start_date=$offers[0]['pos_offers']['start_date'];
                                                $start_time=$offers[0]['pos_offers']['start_time'];
                                                $end_date=$offers[0]['pos_offers']['end_date'];
                                                $end_time=$offers[0]['pos_offers']['end_time'];
                                            }
                                            
                                            
                                            $item[]=array(
                                                'id' => $product['Catalog_product']['id'],
                                                'name' =>  $product['Catalog_product']['name'],
                                                'cat_id' =>  $product['Catalog_product']['cat_id'],
                                                'cat_name' =>  $product['Catalog_product']['cat_name'],
                                                'description' => $product['Catalog_product']['description'],
                                                'food_type' =>  $product['Catalog_product']['food_type'],
                                                'sort_order' =>  $product['Catalog_product']['sort_order'],
                                                'recommended' =>  $product['Catalog_product']['recommended'],
                                                'variation' =>  $product['Catalog_product']['variation'],
                                                'price' => $branchproduct['Catalog_product_branches']['price'],
                                                'kds' => $product['Catalog_product']['kds'],
                                                'markup_price' =>  $product['Catalog_product']['markup_price'],
                                                'allergy_tags' =>  $product['Catalog_product']['allergy_tags'],
                                                'weight' =>  $product['Catalog_product']['weight'],
                                                'serves_people' =>  $product['Catalog_product']['serves_people'],
                                                'type' =>  $product['Catalog_product']['type'],
                                                'image' => $imgpth,
                                                'taxes'=>$taxesitems,
                                                'modifier_group'=>$groupmodifier_items,
                                                'status' =>  $product['Catalog_product']['status'],
                                                'created' =>  $product['Catalog_product']['created'],
                                                'store_id' => $location_ids,
                                                'is_offer' =>  strval($is_offer),
                                                'offer_id' =>  $offer_id ?? '',
                                                'offer_name' =>  $offer_name ?? '',
                                                'offer_type' =>  $offer_type ?? '',
                                                'start_date' =>  $start_date ?? '',
                                                'start_time' =>  $start_time ?? '',
                                                'end_date' =>  $end_date ?? '',
                                                'end_time' =>  $end_time ?? ''
                                            );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            $all_locations[]=array(
                'id' => $location['user_locations']['id'],
                'location_id' =>  $location['user_locations']['location_id'],
                'location_name' =>  $location['user_locations']['location_name']
            );
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                // print_r($tax);exit;
                
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $printers['pos_printers']['name'],
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $printers['pos_printers']['ip'],
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        //dish type
        $dishitems=[];
        $dishes = $this->Catalog_product->query("SELECT dish_type FROM `catalog_product` WHERE status=1 group by dish_type");
        if(!empty($dishes))
        {
            foreach($dishes as $dish){
                if($dish['catalog_product']['dish_type']==0){
                    $dish_name='Food';
                }elseif($dish['catalog_product']['dish_type']==1){
                    $dish_name='Beverage';
                }elseif($dish['catalog_product']['dish_type']==2){
                    $dish_name='Liquor';
                }else{
                    $dish_name='Other';
                }
                $dishitems[]=array(
                    'id' => $dish['catalog_product']['dish_type'],
                    'store_id' =>  $dish['catalog_product']['dish_type'],
                    'name' =>  $dish_name,
                    'kds' =>  $dish['catalog_product']['dish_type'],
                    'ip' =>  $dish['catalog_product']['dish_type'],
                    'status' =>  1
                );
            }
        }
        
        $todayDate = date("Y-m-d");
        $carditems[] = [
            'name'=>'today',
            'value'=>$todayDate
        ];
        $carditems[] = [
            'name'=>'unlimited',
            'value'=>'2030-12-31'
        ];
        $carditems[] = [
            'name'=>'custom',
            'value'=>'custom'
        ];
        
        $paymentitems[] = [
            'name'=>'cash'
        ];
        $paymentitems[] = [
            'name'=>'card'
        ];
        $paymentitems[] = [
            'name'=>'online'
        ];
        
        $response= array('status'=> true,
            'message'=> "success",
            'products'=>$item,
            'category'=>$catitem,
            'printers'=>$printeritems,
            'dishes'=>$dishitems,
            'card_validity'=>$carditems,
            'payment_options'=>$paymentitems,
            'all_locations'=>$all_locations
        );
        return json_encode($response);
    }
    
    public function remove_item_multiple()
    {
        $this->autoRender = false;
    
        // ---------------------------
        // Read Inputs Safely
        // ---------------------------
        $cashierid         = trim($_REQUEST['id'] ?? '');
        $reference_id   = trim($_REQUEST['reference_id'] ?? '');
    
        // ---------------------------
        // Basic Validation
        // ---------------------------
        if (!$cashierid) {
            return json_encode(['status' => false, 'message' => 'Cashier ID is missing']);
        }
        if (!$reference_id) {
            return json_encode(['status' => false, 'message' => 'Reference ID is missing']);
        }
    
        // ---------------------------
        // Validate User
        // ---------------------------
        $user = $this->User->find('first', [
            'conditions' => ['User.id' => $cashierid, 'User.status' => 1],
            'recursive'  => -1
        ]);
    
        if (empty($user)) {
            return json_encode(['status' => false, 'message' => 'User not found']);
        }
    
        // ---------------------------
        // Validate Tables
        // ---------------------------
        $fromtable = $this->Order_table->find('first', [
            'conditions' => [
                'Order_table.reference_id' => $reference_id,
                'Order_table.status'       => 2
            ],
            'recursive' => -1
        ]);
    
        if (empty($fromtable)) {
            return json_encode(['status' => false, 'message' => 'Table not available for Item Remove']);
        }
    
        // ---------------------------
        // Decode JSON
        // ---------------------------
        $json = json_decode($_REQUEST['data'] ?? '', true);
    
        if ($json === null) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON']);
        }
    
        if (empty($json['order_ids']) || !is_array($json['order_ids'])) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON structure: order_ids missing']);
        }
    
        // ---------------------------
        // Process Items (STOP on ANY ERROR)
        // ---------------------------
        $updated = false;
    
        foreach ($json['order_ids'] as $item) {
    
            // ❌ If order_id missing → STOP
            if (empty($item['order_id'])) {
                return json_encode(['status' => false, 'message' => 'Order ID missing in request']);
            }
    
            $order_id = (int)$item['order_id'];
    
            // Fetch order at from table
            $order = $this->Order_orderhistory->find('first', [
                'conditions' => [
                    'Order_orderhistory.id'            => $order_id,
                    'Order_orderhistory.reference_id'  => $reference_id
                ],
                'recursive' => -1
            ]);
    
            // ❌ If order not found → STOP
            if (empty($order)) {
                return json_encode(['status' => false, 'message' => 'Item not available for Remove']);
            }
    
            // Remove TAX records
            $this->Order_tax->updateAll(
                [
                    'Order_tax.status' => 0,
                    'Order_tax.sync'            => 0,
                    'Order_tax.local_sync'      => 0
                ],
                [
                    'Order_tax.orderhistory_id' => $order_id
                ]
            );
            
            $this->Kds_track->updateAll(
                array(
                    'Kds_track.status' => 0,
                    'Kds_track.sync' => 0,
                    'Kds_track.local_sync' => 0
                ),
                array(
                    'Kds_track.order_history_id' => (int)$order_id
                )
            );
            
            // Remove modifier reference
            $this->Order_modifier->updateAll(
                array(
                    'Order_modifier.status' => 0,
                    'Order_modifier.sync' => 0,
                    'Order_modifier.local_sync' => 0
                ),
                array(
                    'Order_modifier.orderhistory_id' => (int)$order_id,
                )
            );
            
            // Remove ORDER item
            $res = $this->Order_orderhistory->updateAll(
                [
                    'Order_orderhistory.status' => 0,
                    'Order_orderhistory.sync'         => 0,
                    'Order_orderhistory.local_sync'   => 0
                ],
                [
                    'Order_orderhistory.id'           => $order_id
                ]
            );
    
            if ($res) {
                $updated = true;
            }
        }
    
        // ---------------------------
        // Final Response
        // ---------------------------
        if ($updated) {
            return json_encode(['status' => true, 'message' => 'Item(s) Removed successfully']);
        }
    
        return json_encode(['status' => false, 'message' => 'No items removed']);
    }
    
    public function void_reprint_data_multiple()
    {
        $cashierid = $_REQUEST['id'];
        $reference_id = $_REQUEST['reference_id'];
        
        $response = array();
        if($cashierid==''){
            $response =array(
                'status'=> false,
                'message'=> "User Id Missing",
            );
            return json_encode($response);
        }
        if($reference_id==''){
            $response =array(
                'status'=> false,
                'message'=> "Reference Id Missing",
            );
            return json_encode($response);
        }
        $users = $this->User->find('first', array('conditions'=>array('User.id'=>$cashierid,'User.status'=>1)));
        if(empty($users))
        {
            $response =array(
                'status'=> false,
                'message'=> "User not found",
            );
            return json_encode($response);
        }
        $canonicalTableRow = $this->Order_table->find('first', [
            'conditions' => ['Order_table.reference_id' => $reference_id, 'Order_table.status IN' => [2, 4]],
            'fields'     => ['Order_table.number'],
            'recursive'  => -1
        ]);
        $canonical_table_number = !empty($canonicalTableRow) ? $canonicalTableRow['Order_table']['number'] : null;

        $orderitems=[];
    // ---------------------------
        // Decode JSON
        // ---------------------------
        $json = json_decode($_REQUEST['data'] ?? '', true);
    
        if ($json === null) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON']);
        }
    
        if (empty($json['order_ids']) || !is_array($json['order_ids'])) {
            return json_encode(['status' => false, 'message' => 'Invalid JSON structure: order_ids missing']);
        }
    
        // ---------------------------
        // Process Items (STOP on ANY ERROR)
        // ---------------------------
        $updated = false;
    
        foreach ($json['order_ids'] as $item) {
            $order_id=$item['order_id'];
            $orderss = $this->Order_orderhistory->query("SELECT * FROM `order_orderhistories` WHERE reference_id='$reference_id' and id='$order_id' and status=0 ");
            if(!empty($orderss))
            {
                foreach($orderss as $orders){
                    $product_id=$orders['order_orderhistories']['product_id'];
                    $order_id=$orders['order_orderhistories']['id'];
                    $selected_modifiers=[];
                    $orders_modifiers = $this->Order_modifier->query("SELECT * FROM `order_modifier` WHERE reference_id='$reference_id' and product_id='$product_id' and orderhistory_id='$order_id' and status=0");
                    foreach($orders_modifiers as $orders_modifier){
                        $modifiers=$orders_modifier['order_modifier'];
                        $modifier_group_id=$modifiers['modifier_group_id'];
                        $modifier_group_name=$modifiers['modifier_group_name'];
                        $modifier_id=$modifiers['modifier_id'];
                        $modifier_name=$modifiers['modifier_name'];
                        $modifier_price=$modifiers['modifier_price'];
                        
                        $selected_modifiers[]=array(
                            'modifier_group_id' => $modifier_group_id,
                            'modifier_group_name' => $modifier_group_name,
                            'modifier_id' => $modifier_id,
                            'modifier_name' => $modifier_name,
                            'modifier_price' => $modifier_price,
                        );
                    }
                    
                    if(!isset($orders['order_orderhistories']['remarks'])){
                        $orders['order_orderhistories']['remarks']='';
                    }
                    $orderitems[]=array(
                        'id' => $orders['order_orderhistories']['id'],
                        'reference_id' =>  $orders['order_orderhistories']['reference_id'],
                        'cashier_id' =>  $orders['order_orderhistories']['cashier_id'],
                        'group_id' =>  $orders['order_orderhistories']['group_id'],
                        'category' =>  $orders['order_orderhistories']['category'],
                        'category_name' =>  $orders['order_orderhistories']['category_name'],
                        'kds' =>  $orders['order_orderhistories']['kds'],
                        'product_id' =>  $orders['order_orderhistories']['product_id'],
                        'product_name' =>  $orders['order_orderhistories']['product_name'],
                        'quantity' =>  $orders['order_orderhistories']['quantity'],
                        'price' =>  $orders['order_orderhistories']['price'],
                        'total_tax' =>  $orders['order_orderhistories']['total_tax'],
                        'total_price' =>  $orders['order_orderhistories']['total_price'],
                        'discount' =>  $orders['order_orderhistories']['discount'],
                        'table_number' =>  $canonical_table_number ?: $orders['order_orderhistories']['table_number'],
                        'kot_number' =>  $orders['order_orderhistories']['kot_number'],
                        'remarks' =>  $orders['order_orderhistories']['remarks'],
                        'selected_modifiers' => $selected_modifiers,
                        'status' =>  $orders['order_orderhistories']['status'],
                        'created' =>  $orders['order_orderhistories']['created']
                    );
                }
            }
        }
        $finalamount=0;
        $transactionitems=[];
        $transactions = $this->Order_transaction->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status'=>0)));
        if(!empty($transactions))
        {
            foreach($transactions as $orders){
                if(!$orders['Order_transaction']['remarks']){
                    $orders['Order_transaction']['remarks']='';
                }
                $finalamount=$orders['Order_transaction']['amount'];
                $cashierid=$orders['Order_transaction']['cashier_id'];
                $reference_id=$orders['Order_transaction']['reference_id'];
                
                $discper = $this->Order_tax->query("SELECT discount_percentage FROM `order_tax` WHERE reference_id='$reference_id' and status=0 and discount_percentage!=0 limit 1");
                if(!empty($discper))
                {
                    $discount_percentage=$discper[0]['order_tax']['discount_percentage'];
                }
                if(!isset($discount_percentage)){
                    $discount_percentage="0";
                }
                
                $transactionitems[]=array(
                    'id' => $orders['Order_transaction']['id'],
                    'reference_id' =>  $orders['Order_transaction']['reference_id'],
                    'orderno' =>  $orders['Order_transaction']['orderno'],
                    'device_id' =>  $orders['Order_transaction']['device_id'],
                    'cashier_id' =>  $orders['Order_transaction']['cashier_id'],
                    'table_number' =>  $canonical_table_number ?: $orders['Order_transaction']['table_number'],
                    'price' =>  $orders['Order_transaction']['price'],
                    'total_tax' =>  $orders['Order_transaction']['total_tax'],
                    'servicecharge' =>  $orders['Order_transaction']['servicecharge'],
                    'discount' =>  $orders['Order_transaction']['discount'],
                    'discount_percentage' =>  $discount_percentage,
                    'discount_type' =>  $orders['Order_transaction']['discount_type'],
                    'discount_type_value' =>  $orders['Order_transaction']['discount_type_value'],
                    'delivery_charge' =>  $orders['Order_transaction']['delivery_charge'],
                    'packing_charge' =>  $orders['Order_transaction']['packing_charge'],
                    'amount' =>  $orders['Order_transaction']['amount'],
                    'round' =>  $orders['Order_transaction']['round'],
                    'name' =>  $orders['Order_transaction']['name'],
                    'phone' =>  $orders['Order_transaction']['phone'],
                    'address' =>  $orders['Order_transaction']['address'],
                    'remarks' =>  $orders['Order_transaction']['remarks'],
                    'status' =>  $orders['Order_transaction']['status'],
                    'tokenno' =>  $orders['Order_transaction']['tokenno'],
                    'createtime' =>  $orders['Order_transaction']['createtime'],
                    'pax' =>  $orders['Order_transaction']['pax'],
                    'created' =>  $orders['Order_transaction']['created']
                );
            }
        }
        
        $paymentitems=[];
        $payments = $this->Order_payment->find('all', array('conditions'=>array('reference_id'=>$reference_id,'status'=>0)));
        if(!empty($payments))
        {
            foreach($payments as $orders){
                if(!isset($orders['Order_payment']['remarks'])){
                    $orders['Order_payment']['remarks']='';
                }
                $paymentitems[]=array(
                    'id' => $orders['Order_payment']['id'],
                    'reference_id' =>  $orders['Order_payment']['reference_id'],
                    'cashier_id' =>  $orders['Order_payment']['cashier_id'],
                    'type' =>  $orders['Order_payment']['type'],
                    'type_value' =>  $orders['Order_payment']['type_value'],
                    'amount' =>  $orders['Order_payment']['amount'],
                    'status' =>  $orders['Order_payment']['status'],
                    'remarks' =>  $orders['Order_payment']['remarks'],
                    'created' =>  $orders['Order_payment']['created']
                );
            }
        }
        $taxitems=[];
        $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");
        if(!empty($taxes))
        {
            foreach($taxes as $tax){
                // print_r($tax);exit;
                
                $taxitems[]=array(
                    'tax_id' => $tax['order_tax']['tax_id'],
                    'tax_name' =>  $tax['order_tax']['tax_name'],
                    'tax_percentage' =>  $tax['order_tax']['tax_percentage'],
                    'tax_value' =>  "" .round($tax[0]['tax_value'],2)
                );
            }
        }
        $finalpayment=0;
        $allpayments=$this->Order_payment->query("SELECT sum(amount) as pay_amount FROM `order_payments` WHERE reference_id='$reference_id' and status=0");
        if($allpayments){
            $finalpayment=$allpayments[0][0]['pay_amount'];
        }
        $amount_diff=round(($finalamount-$finalpayment),2);
        
        $cashier_name='';
        $cashname=$this->User->query("SELECT name FROM `users` WHERE id='$cashierid'");
        if($cashname){
           $cashier_name =$cashname[0]['users']['name'];
        }
        
        $printeritems=[];
        $printerss = $this->Pos_printer->query("SELECT * FROM `pos_printers` WHERE status=1");
        if(!empty($printerss))
        {
            foreach($printerss as $printers){
                if($printers['pos_printers']['name']=='Bar'){
                    $name = $printers['pos_printers']['name'];
                    $ip = $printers['pos_printers']['ip'];
                }else{
                    $name = 'expo';
                    $ip='192.168.1.240';
                }
                $printeritems[]=array(
                    'id' => $printers['pos_printers']['id'],
                    'store_id' =>  $printers['pos_printers']['store_id'],
                    'name' =>  $name,
                    'kds' =>  $printers['pos_printers']['kds'],
                    'ip' =>  $ip,
                    'status' =>  $printers['pos_printers']['status']
                );
            }
        }
        
        $response= array('status'=> true,
                'message'=> "success",  
                'cashier_name'=>$cashier_name,
                'orders'=>$orderitems,
                'transactions'=>$transactionitems,
                'payments'=>$paymentitems,
                'taxes'=>$taxitems,
                'printers'=>$printeritems,
                'remaining_amount'=>number_format($amount_diff, 2, '.', '')
            );
        return json_encode($response);
    }

}
