MOON
Server: Apache
System: Linux nserver.cafsindia.com 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: cafsindia (1002)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //home/cafsindia/hrms_allyindian_com/api/functions.php
<?php
error_reporting(0);
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);
date_default_timezone_set('Asia/Kolkata');
require('./vendor/autoload.php');
require '../phpmailer/src/Exception.php';
require '../phpmailer/src/PHPMailer.php';
require '../phpmailer/src/SMTP.php';
use phpmailer\PHPMailer\PHPMailer;
use phpmailer\PHPMailer\Exception;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
class functions{
    # DB CONNECTION
	private string $host;
    private string $username;
    private string $password;
    private string $database;
	private  $db;
	public $logged_id          = '';
	private $enckey            = 'vDIa5JdknBqfrKOu8d7UpddnBMCH1vza'; //32 characters
    public function db_connect(){
        // require '../application/config/database.php';
        $this->host     = 'localhost';
        $this->username ='cafsindia_adminn';
        $this->password = '60qiBQYcS_@5';
        $this->database = 'allyhrms'; 
        $this->db       = new mysqli($this->host, $this->username, $this->password, $this->database);
        if(mysqli_connect_errno()){
            die("Connection failed: " . $this->db->connect_error);
            return false;
        }else{
            return true;
        }
    }

    # VERIFY DB
    public function checkURL($json){
		// echo "from flutter";
        $link       = $json->link;
        $base_url   = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
        $base_url  .= '://' . $_SERVER['HTTP_HOST'];
        $base_url  .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
        $base_url   = str_replace("/"."api/",'',$base_url);
        if($link === $base_url){
            return $this->returnResult(True, 'Success - proceed', [], []);
        }else{
            return $this->returnResult(False, 'Failed  Unknown URL '.$base_url, [], []);
        }
    }

    # LOGIN VALDIATION
    public function loginProcess($json){
        $code      = $json->code ?? null;
        $pass      = $json->password ?? null;
		$imei_no   = $json->imei_no ?? null; // IMEI NUMBER
        if(!$code || !$pass){
            return $this->returnResult(False, 'Failed - employee code and password required', [], []);
        }
		$emp_rslt            = $this->emp_rslt($code,$pass);		
		
        if($emp_rslt){	
			if($emp_rslt[0]->imei_no){
				$validate_imei   = $this->validate_imei($imei_no,$code);
				if((int)$validate_imei > 0){
					return $this->returnResult(False, 'Failed - Your App is mapped with another mobile.. please contact HR', [], []);
				}
			}else{
				$update_imei_qry = 'UPDATE cw_employees SET imei_no = "'.$imei_no.'" WHERE employee_code = "'.$code.'" AND trans_status = 1';
				$this->runQuery($update_imei_qry);
			}		
			$mobile          = $emp_rslt[0]->mobile_number;
			if($emp_rslt[0]->login_with_otp == 1 || $emp_rslt[0]->first_time_login == 1){
				$otp         = rand(100000, 999999);
				$comp_info   = $this->company_info();
				$sms_otp     = $comp_info[0]->sms_otp; // 1 for sms 2 for mail [MS 06-12-2024]
				if($sms_otp != 1){
					$sms     = $this->send_otp_mail($emp_rslt[0]->company_email_id,$otp);
					$msg     = " Through Mail";
				}else{
					$sms_qry  = 'SELECT sms_content,template_id FROM cw_sms_content WHERE trans_status = 1';
					$sms_info = $this->runQuery($sms_qry);
					$sms_rslt = $this->result($sms_info);					
					$sms_con  = $sms_rslt[0]->sms_content;
					$pattern  = '/@otp@/';
        			$sms_con  = preg_replace($pattern,$otp,$sms_con);
					$sms      = $this->triggersms($mobile,$sms_con);
					$msg      = " Through SMS";
				}
				if(!$sms){
					return $this->returnResult(False, 'Failed - OTP not sent '.$msg.'.please try again later', [], []);
				}
			}
            $userData = [
                'emp_code'              => $emp_rslt[0]->employee_code,
                'emp_name'              => $emp_rslt[0]->emp_name,
                'device_code'           => $emp_rslt[0]->device_code,
                'user_right'            => $emp_rslt[0]->user_right,
                'emp_role'              => $emp_rslt[0]->role,
                'first_time_login'      => $emp_rslt[0]->first_time_login,
                'login_with_otp'        => $emp_rslt[0]->login_with_otp,
                'mobile_checkin'        => $emp_rslt[0]->mobile_checkin,
                'prime_employees_id'    => $emp_rslt[0]->prime_employees_id,
                'first_level_approval'  => $emp_rslt[0]->first_level_approval,
                'second_level_approval' => $emp_rslt[0]->second_level_approval
            ];
			if($otp){
				$emp_rslt[0]->otp       =  $otp; // [MS 06-12-2024]
			}
			
			if($emp_rslt[0]->login_with_otp == 1 || $emp_rslt[0]->first_time_login == 1){
            	$emp_rslt[0]->login_sts =  2; // OTP Verification Pending
			}else{
				$emp_rslt[0]->login_sts =  1; // Valid Login				
			}
			$token    = $this->generate_jwt($emp_rslt[0]); # JWT TOKEN
            return $this->returnResult(True,'Success - code and password verified',[
                'user_data' => $userData,
                'token' => $token
            ], []);
			$this->logged_id = $emp_rslt[0]->prime_employees_id;
        }
        return $this->returnResult(false, 'Failed - Invalid employee code or Password', [], []);
    }

    # JWT TOKEN GENERATION USING FIREBASE PHP LIB
    private function generate_jwt($user){
		$key     = 'Cafs56789'; 
		if($user->loc_allow){
			$loc_qry  = 'SELECT loc_latitude,loc_longitude,radius,location FROM cw_location WHERE trans_status = 1 AND prime_location_id in ('.$user->loc_allow.')';
			$loc_info = $this->runQuery($loc_qry);
			$loc_rslt = $this->result($loc_info);
		}
		$payload = [
			'iat' => time(),
			'exp' => time() + (90 * 24 * 60 * 60),  # expiry
			'user' => [
				'code'                   => $user->employee_code,
				'name'                   => $user->emp_name,
				'role'                   => $user->role,
				'mobile_checkin'         => $user->mobile_checkin,
				'device_code'            => $user->device_code,
				'user_right'             => $user->user_right,
				'prime_employees_id'     => $user->prime_employees_id,
				'first_level_approval'   => $user->first_level_approval,
				'second_level_approval'  => $user->second_level_approval,
				'login_with_otp'         => $user->login_with_otp,
				'otp'         		     => $user->otp,
				'first_time_login' 	     => $user->first_time_login,
				'login_sts' 	         => $user->login_sts
			],
			'allowed_locations' => $loc_rslt ?? []		
		];
        return JWT::encode($payload, $key,'HS256');
    }

    # JWT TOKEN VALIDATION USING FIREBASE PHP LIB
    private function validate_jwt(){
        // return true; // [MS 06-11-2024]
        $headers = apache_request_headers();
        $token   = trim(str_replace('Bearer', '', $headers['authorization'] ?? $headers['Authorization']));
        $key     = 'Cafs56789'; 
        if(!$token){
            $validation_arr['token'] = "Token Is Required";
            echo  $this->returnResult(False,'Invalid Token', [], $validation_arr);
            exit(0);
        }    
        try{
            $decoded = JWT::decode($token, new Key($key, 'HS256'));
            return $decoded->user;
        // }catch(\Firebase\JWT\ExpiredException $e){
        //     echo $this->returnResult(False,'Failed - Token has expired', [], []);
		// 	exit(0);
        // }catch(\Firebase\JWT\SignatureInvalidException $e){
        //     echo $this->returnResult(False,'Failed - Invalid token signature', [], []);
		// 	exit(0);
        // }catch(\Firebase\JWT\BeforeValidException $e){
        //     echo $this->returnResult(False,'Failed - Token not valid yet', [], []);
		// 	exit(0);
        }catch(\Exception $e){
            echo $this->returnResult(False,'Session expired..', [], []);
			exit(0);
        }
    }
	
    # FORGET PASSOWORD
    public function forgetPass($json){
        $code = $json->code ?? null;
        if(!$code){
            return $this->returnResult(False, 'Failed - Employee Code required', [], []);
        }
        $emp_qry  = 'SELECT mobile_number,company_email_id FROM cw_employees WHERE trans_status = 1 AND employee_code = "'.$code.'" ';
        $emp_info = $this->runQuery($emp_qry);
        $emp_rslt = $this->result($emp_info);
        if($emp_rslt){
            $mobile      = $emp_rslt[0]->mobile_number;
            $otp         = rand(100000, 999999);
			$comp_info   = $this->company_info();
			$sms_otp     = $comp_info[0]->sms_otp; // 1 for sms 2 for mail [MS 06-12-2024]
			if($sms_otp != 1){
				$sms     = $this->send_otp_mail($emp_rslt[0]->company_email_id,$otp);
				$msg     = " Through Mail";
			}else{
				$sms_qry     = 'SELECT sms_content,template_id FROM cw_sms_content WHERE trans_status = 1';
				$sms_info    = $this->runQuery($sms_qry);
				$sms_rslt    = $this->result($sms_info);
				$mobile      = $emp_rslt[0]->mobile_number;
				$sms_con     = $sms_rslt[0]->sms_content;
				$pattern     = '/@otp@/';
				$sms_con     = preg_replace($pattern,$otp,$sms_con);
				$sms         = $this->triggersms($mobile,$sms_con);
				$msg      = " Through SMS";
			}
			if(!$sms){
				return $this->returnResult(False, 'Failed - OTP not sent to '.$msg.'.please try again later', [], []);
			}
			$emp_rslt    = $this->emp_rslt($code,"");
			$userData    = [
                'emp_code'              => $emp_rslt[0]->employee_code,
                'emp_name'              => $emp_rslt[0]->emp_name,
                'device_code'           => $emp_rslt[0]->device_code,
                'user_right'            => $emp_rslt[0]->user_right,
                'emp_role'              => $emp_rslt[0]->role,
                'first_time_login'      => $emp_rslt[0]->first_time_login,
                'login_with_otp'        => $emp_rslt[0]->login_with_otp,
                'mobile_checkin'        => $emp_rslt[0]->mobile_checkin,
                'prime_employees_id'    => $emp_rslt[0]->prime_employees_id,
                'first_level_approval'  => $emp_rslt[0]->first_level_approval,
                'second_level_approval' => $emp_rslt[0]->second_level_approval,
            ];
			if($otp){
				$emp_rslt[0]->otp       =  $otp; // [MS 06-12-2024]				
			}
			$emp_rslt[0]->login_sts =  2; // OTP Verification Pending
			$token                      = $this->generate_jwt($emp_rslt[0]);
            return $this->returnResult(True, 'Success - OTP sent '.$msg, ['token' => $token], []);
        }else{
            return $this->returnResult(False, 'Failed - Invalid Employee code', [], []);
        }
    }

    # LOGIN WITH OTP
    public function loginWithotp($json){
		$validate_jwt  = $this->validate_jwt();
		$code          = $json->code ?? null;
        $otp           = $json->otp ?? null;
        if(!$code || !$otp ){
            return $this->returnResult(False, 'Failed - Employee Code required', [], []);
        }
        $login_otp = $validate_jwt->otp;
        if($otp   == $login_otp){
			$emp_rslt               = $this->emp_rslt($code,"");
			$emp_rslt[0]->login_sts =  1; // OTP Verification Pending
			$token                  = $this->generate_jwt($emp_rslt[0]);
            return $this->returnResult(True, 'Success - OTP verified', ['token' => $token], []);
        }else{
            return $this->returnResult(False, 'Failed - Invalid OTP', [], []);
        }
    }

    # RESET PASSWORD
    public function resetPass($json){
        $code          = $json->code ?? null;
        $otp           = $json->otp ?? null;
        $newPass       = $json->newPass ?? null;
        $conPass       = $json->conPass ?? null;
		$validate_jwt  = $this->validate_jwt(); // HEADER TOKEN 
        if($newPass !== $conPass){
            return $this->returnResult(False, 'New And Confirm Password Must be Same', [], []);
        }
        if(!$code || !$otp || !$newPass){
            return $this->returnResult(False, 'Failed - Employee Code,otp,passwords required', [], []);
        }
        $login_otp            = $validate_jwt->otp;
        $login_code           = $validate_jwt->code;
        $first_time           = $validate_jwt->first_time_login;
        if(strval($otp) === strval($login_otp) && strval($code) === strval($login_code)){
            $emp_qry          = 'SELECT password,password_log FROM cw_employees WHERE trans_status = 1 AND employee_code = "'.$code.'" ';
            $emp_info         = $this->runQuery($emp_qry);
            $emp_rslt         = $this->result($emp_info);
            $oldPass          = $emp_rslt[0]->password ?? 0;
			$old_pass_log     = $emp_rslt[0]->password_log;
			$old_pass_arr     = explode('||',$old_pass_log);
			$company_info     = $this->company_info();
			$pass_log_count   = $company_info[0]->password_log; 

            if($oldPass == $this->cryptoEncrypt(MD5($newPass))){
                return $this->returnResult(False, 'Failed - Old and new passwords must be different', [], []);
            }else{
				if($first_time === "1"){
					$first_time_qry  = ' ,first_time_login = 2 ';
				}
				$con_pass = $this->cryptoEncrypt(MD5($newPass));
				if((int)count($old_pass_arr ?? []) === (int)$pass_log_count){
					if(in_array($con_pass,$old_pass_arr)){
						return $this->returnResult(False, "Your new password must be different from your last $pass_log_count passwords. Please choose a unique password to continue.", [], []);
						exit(0);
					}else{
						unset($old_pass_arr[0]);
						$old_pass_arr[] = $con_pass;
						$pass_log       = implode('||',$old_pass_arr);
					}
				}else{
					$pass_log      = $old_pass_log.'||'.$con_pass;
				}
				$upd_qry  = 'UPDATE cw_employees SET password = "'.$con_pass.'", password_log = "'.$pass_log.'" '.$first_time_qry.' WHERE employee_code = "'.$code.'" AND trans_status = 1';
                $upd_info = mysqli_query($this->db,$upd_qry);
                $aff_rows = mysqli_affected_rows($this->db);
                if($aff_rows){
					$emp_rslt               = $this->emp_rslt($code,"");
					$emp_rslt[0]->login_sts =  1; // OTP Verification Pending
					$token                  = $this->generate_jwt($emp_rslt[0]);
                    return $this->returnResult(True, 'Success - Password updated', ['token' => $token], []);
                }else{
                    return $this->returnResult(False, 'Failed - Password not updated', [], []);
                }
            }
        }else{
            return $this->returnResult(False, 'Failed - OTP or employee code Mismatch', [], []);
        }
    }

    # PASSWORD CHANGE
    public function passChange($json){  
        $this->validate_jwt();       
        $code     = $json->code ?? null;
        $cur_pass = $json->curPass ?? null;
        $new_pass = $json->newPass ?? null;
        $con_pass = $json->conPass ?? null;
        $pattern  = '/^(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/';
        if(!$code || !$new_pass || !$con_pass || !$cur_pass){
            return $this->returnResult(False, 'Failed - Employee Code,passwords required', [], []);
        }
        $emp_qry  = 'SELECT password,password_log FROM cw_employees WHERE trans_status = 1 AND employee_code = "'.$code.'" ';
        $emp_info = $this->runQuery($emp_qry);
        $emp_rslt = $this->result($emp_info);
        if($emp_rslt){
            $oldPass          = $emp_rslt[0]->password;
            $old_pass_log     = $emp_rslt[0]->password_log;
			$old_pass_arr     = explode('||',$old_pass_log);
			$company_info     = $this->company_info();
			$pass_log_count   = $company_info[0]->password_log;

            if($oldPass != $this->cryptoEncrypt(MD5($cur_pass))){
                return $this->returnResult(False, 'Failed - Invalid current password', [], []);
            }else
            if($oldPass == MD5($con_pass)){
                return $this->returnResult(False, 'Failed - Old and new passwords must be different', [], []);
            }else
            if(!preg_match($pattern, $con_pass)){
                return $this->returnResult(false, 'Failed - Password must be at least 8 characters long, include an uppercase letter, a digit, and a special character.', [], []);
            }else{
                if($new_pass == $con_pass){
					$con_pass = $this->cryptoEncrypt(MD5($con_pass));
					if((int)count($old_pass_arr ?? []) === (int)$pass_log_count){
						if(in_array($con_pass,$old_pass_arr)){
							return $this->returnResult(False, "Your new password must be different from your last $pass_log_count passwords. Please choose a unique password to continue.", [], []);
							exit(0);
						}else{
							unset($old_pass_arr[0]);
							$old_pass_arr[] = $con_pass;
							$pass_log       = implode('||',$old_pass_arr);
						}
					}else{
						$pass_log      = $old_pass_log.'||'.$con_pass;
					}
                    $upd_qry  = 'UPDATE cw_employees SET password = "'.$con_pass.'", password_log = "'.$pass_log.'"  WHERE employee_code = "'.$code.'" AND trans_status = 1';
                    $upd_info = mysqli_query($this->db,$upd_qry);
                    $aff_rows = mysqli_affected_rows($this->db);
                    if($aff_rows){
                        return $this->returnResult(True, 'Success - Password Reset successful', [], []);
                    }else{
                        return $this->returnResult(False, 'Failed - Password not updated', [], []);
                    }
                }else{
                    return $this->returnResult(False, 'Failed - password Mismatch', [], []);
                }
            }
        }else{
            return $this->returnResult(False, 'Failed - Unknown Employee code', [], []);
        }
    }

    # COMMON DROP
    public function commonDrop($json){
        $this->validate_jwt(); 
        $dropList = $json->dropList;
        $module   = $json->module;
        $labels   = implode(',',array_map(function($val){ 
            return '"'.$val->pro_for.'"'; # LABEL NAME
        },$dropList) ?? []);
        $id_array = []; # PRIME ID 
        $sort_by  = []; # SORT
        foreach($dropList as $drop){
            $id_array[$drop->pro_for] = implode(',',array_map(function($val){
                return '"'.$val.'"';
            },$drop->pro_val) ?? []);
            $sort_by[$drop->pro_for]  = $drop->sort;
        }
        # FORM SETTING
        $form_qry   = 'SELECT DISTINCT(pick_table) as pick_table, pick_list, label_name FROM cw_form_setting WHERE trans_status = 1 AND label_name IN ('.$labels.') AND field_type IN (5,7,9) AND prime_module_id = "'.$module.'"';
        $form_info  = $this->runQuery($form_qry);
        $form_rslt  = $this->result($form_info);
        $form_array = [];
        foreach($form_rslt as $form){
            $label_name      = $form->label_name;
            $pick_list       = $form->pick_list;
            $pick_list_val   = explode(",", $pick_list ?? "");
            $pick_list_val_1 = $pick_list_val[0];
            $pick_list_val_2 = $pick_list_val[1];
            $pick_table      = $form->pick_table;
            $primeId         = $id_array[$label_name];
            $sortBy          = $sort_by[$label_name];
            $sort_cond       = "";
            if($sortBy === "2"){
                $sort_cond   = "ORDER BY $pick_list_val_1 DESC";
            }
            $filter_cond     = "";
            if($primeId){
                $filter_cond = "AND $pick_list_val_1 IN ($primeId)";
            }
            $pick_query      = "SELECT $pick_list FROM $pick_table WHERE trans_status = 1 $filter_cond $sort_cond";
            $pick_info       = $this->runQuery($pick_query);
            $pick_rslt       = $this->result($pick_info);  
            $form_array[$label_name]   = [];
            $form_array[$label_name][] = ["value" => "","label" => "-- Select ".ucwords(str_replace('_',' ',$label_name))." --","isdisabled" => true];
            foreach($pick_rslt as $row){
                $form_array[$label_name][] = [
                    "value" => $row->$pick_list_val_1,
                    "label" => $row->$pick_list_val_2
                ];
            }
        }
        if(!$form_array){
            return $this->returnResult(True, 'Failed - No Data Found', [], []);
        }
        return $this->returnResult(True,'Success - Proceed',['user_data' => $form_array], []);
    }

    # FUNCTION FOR EMPLOYEE SHIFT NAME AND PUNCH IN AND OUT TIME GET
    public function punchData($json){
        $this->validate_jwt(); 
        $code       = $json->code ?? null;
        $shift_date = $json->shift_date ?? null;
        if(!$code || !$shift_date){
            return $this->returnResult(False, 'Failed - Employee Code,shift date required', [], []);
        }
        $shift_qry  = 'SELECT cw_shift_master.shift_name,cw_time_entry.punch_in,cw_time_entry.punch_out FROM cw_time_entry INNER JOIN cw_shift_master ON cw_shift_master.prime_shift_master_id = cw_time_entry.shift_id WHERE cw_time_entry.employee_code = "'.$code.'" AND cw_time_entry.att_date = "'.$shift_date.'" AND cw_time_entry.trans_status = 1';
        $shift_info = $this->runQuery($shift_qry);
        $shift_rslt = $this->result($shift_info);
        if($shift_rslt){
            $shift_name = $shift_rslt[0]->shift_name;
            $punch_in   = ($shift_rslt[0]->punch_in && $shift_rslt[0]->punch_in !== "0000-00-00 00:00:00") ? date("d-m-Y H:i", strtotime($shift_rslt[0]->punch_in)) : '';
            $punch_out  = ($shift_rslt[0]->punch_out && $shift_rslt[0]->punch_out !== "0000-00-00 00:00:00") ? date("d-m-Y H:i", strtotime($shift_rslt[0]->punch_out)) : '';
            if(!$punch_in || !$punch_out){
                return $this->returnResult(False, 'Failed - Punch Data not Available.!', [], ['shift_name' => $shift_name]);
            }
            $userData = [
                'shift_name' => $shift_name,
                'punch_in' => $punch_in,
                'punch_out' => $punch_out
            ];
            return $this->returnResult(True,'Success -  Punch and Shift data',['user_data' => $userData], []);
        }else{
            return $this->returnResult(True, 'Failed - No Data Found', [], []);
        }
    }

    # SHIFT ALLOCATED FOR PARTICULAR DATE
    public function empShiftData($json){
        $this->validate_jwt(); 
        $code       = $json->code;
        $shift_date = $json->shift_date;
        $fin_info   = $this->get_leave_financial_details();
        $fin_id     = $fin_info[0]->prime_leave_financial_year_id;
        if($fin_id){
            # SHIFT NAME 
            $shift_qry  = 'SELECT shift_name FROM cw_shift_import WHERE cw_shift_import.employee_code = "'.$code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.financial_setting_id= "'.$fin_id.'" and cw_shift_import.trans_status = 1';
            $shift_info = $this->runQuery($shift_qry);
            $shift_rslt = $this->result($shift_info);
            if($shift_rslt){
                $shift_name = $shift_rslt[0]->shift_name;
                return $this->returnResult(True,'Success -  Shift Name',['user_data' => ['shift_name' => $shift_name]], []);
            }else{
                return $this->returnResult(False, 'Failed - Shift not Allocated for this Date Please Contact Admin.!', [], []);
            }
        }else{
            return $this->returnResult(False, 'Failed - Kindly check leave financial setting', [], []);
        }
    }

    # ADD/UPDATE DATA
    public function addUpdate($json){
        $this->validate_jwt(); # JWT TOKEN
        $module       = $json->module;
        $apidata      = $json->data;
        $prime_id     = $json->primeId;
        $requestType  =  $json->requestType;
        # VALIDATIONS
        $validation   = $this->validations($apidata,$module,$requestType);
        if($validation){
            return json_encode(['status' => False,'message' => 'Failed - Validation Error','data' => $validation]);
            exit(0);
        }else{
            $module = "cw_".$json->module;
            $prime_name = "prime_".$json->module."_id";
            if($prime_id){
                $upd_parts  = [];
                foreach($apidata as $key => $data){
                    $upd_parts[] = "$key = '" .$data. "'";
                }
                $upd_qry    = "UPDATE $module SET ".implode(",",$upd_parts ?? [])." WHERE trans_status = 1 AND $prime_name = $prime_id";
                $upd_info   = mysqli_query($this->db,$upd_qry);
                $aff_rows   = mysqli_affected_rows($this->db);
                if($aff_rows){
                    return $this->returnResult(True, 'Success - Data updated', [], []);
                }else{
                    return $this->returnResult(False, 'Failed - Not Updated', [], []);
                }
            }else{
                $ins_keys   = [];
                $ins_values = [];
                foreach($apidata as $key => $data){
                    $ins_keys[]   = "$key";
                    $ins_values[] = '"' . $data . '"';
                }
                $ins_qry    = "INSERT INTO $module (".implode(",",$ins_keys ?? []).") VALUES (".implode(",",$ins_values ?? []).")";
                $ins_info   = mysqli_query($this->db,$ins_qry);
                $ins_id     = $this->db->insert_id;
                if($ins_id){
                    return $this->returnResult(True, 'Success - Data Inserted', [], []);
                }else{
                    return $this->returnResult(False, 'Failed - Not Inserted', [], []);
                }
            }
        }
    }

    # DELETE
    public function delete($json){
       	$this->validate_jwt(); # JWT TOKEN
        $id          = explode(',',$json->id ?? "");
        if(!$id){
            return $this->returnResult(False, 'Failed - Select data to delete', [], []);
        }
        $module      = "cw_".$json->module;
        $prime_name  = "prime_".$json->module."_id";
        $id          = '"'.implode('","',$id ?? []).'"';
        $delete_qry  = "UPDATE $module SET trans_status = 1 WHERE $prime_name IN ($id) ";
        $delete_info = mysqli_query($this->db,$delete_qry);
        $aff_rows    = mysqli_affected_rows($this->db);
        if(!$aff_rows){
            return $this->returnResult(False, 'Failed - Not Deleted', [], []);
        }
        return $this->returnResult(True, 'Success - Data Deleted', [], []);
    }

    # GRANTS 
    public function grants($json){
        $jwt_token   = $this->validate_jwt(); # JWT TOKEN
        $prime_id    = $jwt_token->prime_employees_id;
        $grants_qry  = 'SELECT permission_id,access_add,access_update,access_delete,access_search,access_export,access_import FROM cw_grants WHERE prime_employees_id = "'.$prime_id.'" ';
        $grants_info = $this->runQuery($grants_qry);
        $grants_rslt = $this->result($grants_info);
        if($grants_rslt){
            return $this->returnResult(True, 'Success - Permission for above employee',['user_data' => ['data' => $grants_rslt]], []);
        }else{
            return $this->returnResult(True, 'Failed - No permissions given to this employee.', ['user_data' =>['data' =>[]]], []);
        }
    }

    # SEARCH TABLE DATA
    public function searchData($json){
        $this->validate_jwt(); # JWT TOKEN
        $code       = $json->code;
        $start      = $json->start;
        $perPage    = $json->perPage;
        $sortBy     = $json->sortBy;
        $sortOrder  = $json->sortOrder;
        $filter     = $json->filter;
        $module     = "cw_".$json->module;
        $search_val = $json->search_val;
        $search_col = $json->search_col;
        if($module){
            $common_search  = '';
            if($search_val){
                $search_col = explode(',',$search_col ?? "");
                foreach($search_col as $search_label){
                    $common_search .= ' or '. $search_label .' like "'.$search_val.'%"';
                }
                if($common_search){
                    $common_search = ltrim($common_search,' or ');
                    $common_search = " and ($common_search)";
                    $common_search = str_replace("(,","(",$common_search);
                    $common_search = str_replace("()","(0)",$common_search);
                }
            }
            # TABLE DATA
            $search_query = 'SELECT * FROM '.$module.' WHERE trans_status = 1 AND employee_code ="'.$code.'" '.$common_search.'';
            $search_query.= " ORDER BY $sortBy $sortOrder";
            if((int)$perPage !== -1){
                $search_query .= " LIMIT $start,$perPage";
            }   
            $search_info  = $this->runQuery($search_query);
            $search_rslt  = $this->result($search_info);

            # FILTER DATA COUNT
            $filter_query = "SELECT count(*) as allcount FROM $module WHERE trans_status = 1 $common_search";
            $filter_info  = $this->runQuery($filter_query);
            $filter_rslt  = $this->result($filter_info);
            $filter_count = $filter_rslt[0]->allcount;

            # TOTAL DATA COUNT
            $total_query  = "SELECT count(*) as allcount FROM $module WHERE trans_status = 1";
            $total_info   = $this->runQuery($total_query);
            $total_rslt   = $this->result($total_info);
            $total_count  = $total_rslt[0]->allcount;
            if(!$search_rslt){
                return $this->returnResult(True, 'Failed - No Data Found', [], []);
            }
            $userData = [
                'data' =>  $search_rslt,
                'recordsTotal' => $total_count,
                'recordsFiltered' => $filter_count
            ];
            return $this->returnResult(True,'Success - Data to display',['user_data' => $userData], []);
        }
    }

    # PUNCH IN 
    public function checkIn($json){
		$validate_jwt = $this->validate_jwt(); # JWT TOKEN
        $emp_id       = $validate_jwt->prime_employees_id;
        $code         = $validate_jwt->code;
        $punchIn      = $json->punchIn ?? null;
        $deviceCode   = $json->deviceCode ?? null;
        $location     = $json->location ?? null;
        $latitude     = $json->latitude ?? null;
        $longitude    = $json->longitude ?? null;
        $img_path     = $json->img_path ?? null; 
        if(!$punchIn){ // || !$deviceCode || !$location || !$latitude || !$longitude
            return $this->returnResult(False, 'Failed - punchIn required', [], []);
        }
		$path = "";
		if(!$deviceCode){
			return $this->returnResult(False, 'Failed - Device code not mapped to this employee..', [], []);
		}

		if($img_path){
			$upload_arr = $this->upload_files($img_path,"checkIn","time_log","in_out_img");    
			if($upload_arr['sts'] === "FALSE"){
				return $this->returnResult(False, $upload_arr['msg'], [], []);
			}
			$path       = $upload_arr['path'];
		}
		
        $ins_qry    = 'INSERT INTO cw_time_log(log_date,user_id,device_id,record_type,location,latitude,longitude,in_out_img,trans_created_by,trans_created_date) VALUES ("'.$punchIn .'","'.$deviceCode .'","MOBIN","in","'.$location .'","'.$latitude .'","'.$longitude.'","'.$path.'","'.$emp_id.'","'.date("Y-m-d H:i:s").'")';
        mysqli_query($this->db,$ins_qry);
        $ins_id     = $this->db->insert_id;
        if(!$ins_id){
            return $this->returnResult(False, 'Failed - Not Inserted', [], []);
        }else{
			// $this->runQuery("CALL itsp_prcatt ('".date("Y-m-d")."','".date("Y-m-d")."','$code')");
            return $this->returnResult(True, 'Success - Successfully checked In', [], []);
        }
    }

	# PUNCH OUT 
	public function checkOut($json){
		$validate_jwt = $this->validate_jwt(); # JWT TOKEN
		$emp_id       = $validate_jwt->prime_employees_id;
		$code         = $validate_jwt->code;
		$punchOut     = $json->punchOut ?? null;
		$deviceCode   = $json->deviceCode ?? null;
		$location     = $json->location ?? null;
		$latitude     = $json->latitude ?? null;
		$longitude    = $json->longitude ?? null;
		$img_path     = $json->img_path ?? null;
		if(!$punchOut ){ //|| !$deviceCode || !$location || !$latitude || !$longitude
			return $this->returnResult(False, 'Failed - punchOut', [], []);
		}
		$path = "";
		if($img_path){
			$upload_arr = $this->upload_files($img_path,"checkOut","time_log","in_out_img");   
			if($upload_arr['sts'] === "FALSE"){
				return $this->returnResult(False, $upload_arr['msg'], [], []);
			}
			$path       = $upload_arr['path'];
		}
		$ins_qry  = 'INSERT INTO cw_time_log(log_date,user_id,device_id,record_type,location,latitude,longitude,in_out_img,trans_created_by,trans_created_date) VALUES ("'.$punchOut .'","'.$deviceCode.'","MOBOUT","out","'.$location .'","'.$latitude .'","'.$longitude.'","'.$path.'","'.$emp_id.'","'.date("Y-m-d H:i:s").'")';			
		mysqli_query($this->db,$ins_qry);
		$ins_id   = $this->db->insert_id;
		if(!$ins_id){
			return $this->returnResult(False, 'Failed - Not Inserted', [], []);
		}
		// $this->runQuery("CALL itsp_prcatt ('".date("Y-m-d")."','".date("Y-m-d")."','$code')");
		return $this->returnResult(True, 'Success - Successfully checked Out', [], []);
	}

    # LOAN INSTALLMENT
    public function loanInstallment($json){
		$this->validate_jwt();
        $employee_code  = $json->code;
        $loan_id        = $json->loanId;
        $loan_qry       = 'SELECT cw_loan_installment.install_year,cw_loan_installment.paid_status,cw_loan_installment.install_amount,cw_loan_installment.installment_count FROM cw_loan INNER JOIN cw_loan_installment ON cw_loan.prime_loan_id = cw_loan_installment.loan_id WHERE cw_loan.emp_code = "'.$employee_code.'" AND cw_loan_installment.loan_id = "'.$loan_id.'" AND cw_loan.trans_status = 1 GROUP BY cw_loan_installment.prime_loan_installment_id';
        $loan_info      = $this->runQuery($loan_qry);
		$loan_rslt      = $this->result_array($loan_info);

        if(count($loan_rslt ?? []) > 0){
            $rslt       = array();
            foreach($loan_rslt as $rslt_arr){
               $rslt[$rslt_arr['install_year']] = $rslt_arr;
            }
            return $this->returnResult(True,'Success',$rslt, []);
        }else{
            $validation_arr['No data']   = 'No data Found' ;
            return $this->returnResult(True,'Failed', [], $validation_arr);
        }
    }

    # WORKSHEET
    public function worksheet($json){
		$this->validate_jwt(); # JWT TOKEN
        $code     = $json->code ?? null;
        $frm_mon  = $json->frmMon ?? null;
        $to_mon   = $json->toMon ?? null;
		$fromToMonthValid  = $this->fromToMonthValidation($frm_mon,$to_mon,"month");
		if($fromToMonthValid){
			return $this->returnResult(False, 'To Month Must Be Greater Than From Month', [], []);
		}
        if(!$code || !$frm_mon  || !$to_mon ){
            return $this->returnResult(False, 'Failed - code,Frm and to month required', [], []);
        }
        $db_name  = $this->database;
        $start    = strtotime(date('Y-m-d', strtotime("01-".$frm_mon)));
        $end      = strtotime(date('Y-m-d', strtotime("01-".$to_mon)));
        $cat_qry  = 'SELECT category_name FROM cw_employees INNER JOIN cw_category ON cw_category.prime_category_id = cw_employees.role WHERE employee_code = "'.$code.'"';
        $cat_info = $this->runQuery($cat_qry);
        $cat_rslt = $this->result($cat_info);
        $category = strtolower(str_replace(" ","_",$cat_rslt[0]->category_name));
        $pdf      = '';
        while($start <= $end){
            $wrksheet_mon    = date('m-Y', $start);
            $wrksheet_name   = "WSHEET_".strtoupper(date('F_Y', $start));
            $file_name       = $db_name."_".$code."_".$wrksheet_mon; 
            $enc_file        = $this->encryptFilename($file_name,$db_name);   
            $enc_file_name   =  $enc_file."_".$code;
            if($db_name === "hare_hrms_db"){
                $month_year  =  date('Y-m', $start);
                $check_month = "2023-08";
                if($month_year <= $check_month){
                    $payslip_month_name = "C0001_".strtoupper(date('F_Y', $start));
                    $file_path = "worksheet/$wrksheet_name/WSHEET_$code.pdf";
                }else{
                    $file_path = "worksheet/$category/$wrksheet_mon/$enc_file_name.pdf";
                }               
            }else{
                $file_path = "worksheet/$category/$wrksheet_mon/$enc_file_name.pdf";
            }   
            $filename                     = dirname(__FILE__).$file_path;
            $filename                     = str_replace("api","",$filename);
            if(file_exists($filename)){
                $filename                 = $this->baseurl($file_path);      
                $pdf                      = $filename;
                $pdf_arr[$wrksheet_mon]   = $pdf;
            }
            $start = strtotime("+1 month", $start);
        }
        $pdf = rtrim($pdf,',');
        if(!$pdf){
            return $this->returnResult(True, 'Failed - No Data Found', [], []);
        }
        return $this->returnResult(True,'Success - worksheet generated for the above employees',['files' => $pdf_arr, 'password' => 1], []);
    }

    # FORM16
    public function form16($json){
        $this->validate_jwt(); # JWT TOKEN
        $db_name      = $this->database; // DOUBT
        $code         = $json->code ?? null;
        $fin_yr       = $json->finYr ?? null;
        $pdf          = '';
        if(!$code || !$fin_yr){
            return $this->returnResult(False, 'Failed - code,Fin year required', [], []);
        }
        $pan_num_qry  = 'SELECT pan_number FROM cw_employees WHERE employee_code = "'.$code.'"';
        $pan_num_info = $this->runQuery($pan_num_qry);
        $pan_num_rslt = $this->result($pan_num_info);
        $pan_number   = $pan_num_rslt[0]->pan_number; 
        if(!$pan_number){
            return $this->returnResult(False, 'Failed - Pan number is empty', [], []);
        }
        if($db_name === "hare_hrms_db"){
            $month_year    =  date('Y', $fin_yr);
            $check_month   = "2022-23";
            if($fin_yr <= $check_month){
               $file_path  = "form_16/form_16_$fin_yr/".strtoupper($pan_number).".pdf";
            }else{
                $file_path = "form_16B/form_16B_$fin_yr/".$code.".pdf";
            }               
        }else{
			$com_qry           = 'SELECT payslip_based_on,encrypted_pdf FROM cw_company_information WHERE trans_status = 1';
			$com_info          = $this->runQuery($com_qry);
			$com_rslt          = $this->result($com_info);
			$enc_pdf           = (int)$com_rslt[0]->encrypted_pdf;
			if($enc_pdf === 1){
				$file_name     = $db_name."_".$code."_".$fin_yr;
				$enc_file      = $this->encryptFilename($file_name,$db_name);  
				$enc_file_name = $enc_file."_".$code;
			}else{
				$enc_file_name = $code;
			}
            $file_path   = "form_16b/form_16b_$fin_yr/".$enc_file_name.".pdf";
        }   
        $filename        = dirname(__FILE__).$file_path;
        $filename        = str_replace("api","",$filename);
        if(file_exists($filename)){
            $filename    = $this->baseurl($file_path);    
            $pdf         = $filename;
            $pdf_arr[$fin_yr]   = $pdf;
            return $this->returnResult(True,'Success - form16 for the following employee',['files' => $pdf_arr , 'password' => 2], []);
        }else{
            return $this->returnResult(True, 'Failed - No Data Found', [], []);
        }
    }

    # TIMECARD
    public function timecard($json){
        $this->validate_jwt(); # JWT TOKEN
        $code      = $json->code ?? null;
        $month     = $json->processMonth ?? null;
        if(!$code || !$month){
            return json_encode(['status'  => False,'message' => 'Failed - Emp code,process_month required']);
        }
		$timecard_rslt    = $this->get_timecard_design($code,$month);
		if($timecard_rslt){
			return $this->returnResult(True,'Success - timecard for the following employee',$timecard_rslt, []);
		}else{
			return $this->returnResult(True, 'Failed - No Data Found', [], []);
		}
    }


	public function get_timecard_design($emp_code,$timecard_month){
		//Get from date & to date to generate timecard design
		$salary_arr          = $this->tos_sal_strt_end_info("4",$timecard_month);
		$salary_start_date   = date("Y-m-d",strtotime($salary_arr['salary_start_date']));
		$salary_end_date     = date("Y-m-d",strtotime($salary_arr['salary_end_date']));
		$time_qry 	         = 'SELECT employee_code,att_date,punch_in,punch_out,final_total_work_hours as total_work_hours,total_late_hours,total_excess_hours,whole_day_status,permission_in,permission_out,total_permission,early_out,late_in FROM cw_time_entry where cw_time_entry.trans_status = 1 and employee_code = "'.$emp_code.'" and att_date between "'.$salary_start_date.'" and "'.$salary_end_date.'"';
		$time_info           = $this->runQuery($time_qry);
		$time_rslt        	 = $this->result_array($time_info);		
		$time_rslt = [];
		foreach ($time_info as $arr) {
			$time_rslt[$arr['employee_code']][$arr['att_date']] = $arr;
		}

		//
		$holiday_rslt        = $this->holiday_status($emp_code);		
		// Get Leave Entry
		$leave_entry_qry     = 'SELECT employee_code,leave_date,leave_type,cw_leave_creation.leave_description FROM cw_leave_entry INNER JOIN cw_leave_creation ON cw_leave_entry.leave_type = cw_leave_creation.prime_leave_creation_id where cw_leave_entry.employee_code = "'.$emp_code.'" AND leave_date between "'.$salary_start_date.'" and "'.$salary_end_date.'" AND cw_leave_entry.trans_status = 1 and leave_status = 2';
		$leave_entry_info    = $this->runQuery($leave_entry_qry);
		$leave_entry_rslt    = $this->result_array($leave_entry_info);
		$leave_entry_rslt    = [];
		foreach ($leave_entry_info as $arr) {
			$leave_entry_rslt[$arr['leave_date']] = $arr;
		}
		
		//Build Leave name & Holiday
		foreach($time_rslt[$emp_code] as $val){
			$att_date        = $val['att_date'];
			//echo "BSK $att_date <br/>";
			if(array_key_exists($att_date,$holiday_rslt ?? [])){
				$time_rslt[$emp_code][$att_date]['desc']        = $holiday_rslt[$att_date]->holiday_description;
			}
			if(array_key_exists($att_date,$leave_entry_rslt ?? [])){
				$time_rslt[$emp_code][$att_date]['desc']        = $leave_entry_rslt[$att_date]['leave_description'];
			}
		}
		//Get Shift Result
		$shift_qry      	 = 'SELECT employee_code,att_date,short_name FROM cw_time_entry inner join cw_shift_master on cw_shift_master.prime_shift_master_id = cw_time_entry.shift_id where cw_time_entry.trans_status = 1 and cw_time_entry.employee_code = "'.$emp_code.'" and att_date between "'.$salary_start_date.'" and "'.$salary_end_date.'"';
		$shift_info          = $this->runQuery($shift_qry);
		$shift_rslt 	     = $this->result_array($shift_info);

		$shift_rslt          = array_reduce($shift_rslt ?? [], function ($result, $arr) {
		    $result[$arr['employee_code']][$arr['att_date']] = $arr;
		    return $result;
		}, array());

		$holiday_qry 	     = 'SELECT holiday_date FROM cw_holiday_entry inner join cw_holiday_entry_holiday_data on cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id where cw_holiday_entry_holiday_data.trans_status = 1 and holiday_date between "'.$salary_start_date.'" and "'.$salary_end_date.'"';
		$holiday_info        = $this->runQuery($holiday_qry);
		$holiday_rslt 	     = $this->result_array($holiday_info);

		$holiday_rslt        = array_reduce($holiday_rslt ?? [], function ($result, $arr) {		
		    $result[$arr['holiday_date']] = $arr;
		    return $result;
		}, array());

		$weekoff_qry 	     = 'SELECT employee_code,weekoff_date,weekoff_type FROM cw_weekoff_import where cw_weekoff_import.trans_status = 1 and weekoff_date between "'.$salary_start_date.'" and "'.$salary_end_date.'" and employee_code = "'.$emp_code.'"';
		$weekoff_info        = $this->runQuery($weekoff_qry);
		$weekoff_rslt 	     = $this->result_array($weekoff_info);

		$weekoff_rslt        = array_reduce($weekoff_rslt ?? [], function ($result, $arr) {
		    $result[$arr['employee_code']][$arr['weekoff_date']] = $arr;
		    return $result;
		}, array());

		//Get Date Period Between Two Dats
		$date_period         = new DatePeriod(
			new DateTime($salary_start_date),
			new DateInterval('P1D'),
			new DateTime(date("Y-m-d",strtotime("+1 days",strtotime($salary_end_date))))
		);
		$leave_arr           = array("L"=>1,"FL"=>0.5,"SL"=>0.5,"LP"=>0.5,"PL"=>0.5,"LM"=>0.5,"ML"=>0.5,"OL"=>0.5,"LO"=>0.5,"LL"=>1,"WL"=>0.5,"LW"=>0.5,"UL"=>0.5,"LU"=>0.5,"IL"=>0.5,"LI"=>0.5);
		$present_arr         = array("P"=>1,"FP"=>0.5,"SP"=>0.5,"LP"=>0.5,"PL"=>0.5,"PM"=>0.5,"MP"=>0.5,"OP"=>0.5,"PO"=>0.5,"PP"=>1,"IP"=>0.5,"PI"=>0.5,"PU"=>0.5,"UP"=>0.5);
		$onduty_arr          = array("O"=>1,"FO"=>0.5,"SO"=>0.5,"OP"=>0.5,"PO"=>0.5,"OM"=>0.5,"MO"=>0.5,"OL"=>0.5,"LO"=>0.5,"OO"=>1,"WO"=>0.5,"OW"=>0.5,"UO"=>0.5,"OU"=>0.5,"IO"=>0.5,"OI"=>0.5);
		$mpunch_arr          = array("M"=>1,"FM"=>0.5,"SM"=>0.5,"MP"=>0.5,"PM"=>0.5,"OM"=>0.5,"MO"=>0.5,"ML"=>0.5,"LM"=>0.5,"MM"=>1,"WM"=>0.5,"MW"=>0.5,"UM"=>0.5,"MU"=>0.5,"IM"=>0.5,"MI"=>0.5);
		$weekoff_arr         = array("W"=>1,"WL"=>0.5,"LW"=>0.5,"WO"=>0.5,"OW"=>0.5,"WM"=>0.5,"MW"=>0.5);
		$unpunch_arr         = array("U"=>1,"UL"=>0.5,"LU"=>0.5,"UO"=>0.5,"OU"=>0.5,"UM"=>0.5,"MU"=>0.5,"UP"=>0.5,"PU"=>0.5,"FP"=>0.5,"SP"=>0.5,"IU"=>0.5,"UI"=>0.5,"FL"=>0.5,"SL"=>0.5);
		$invalid_arr         = array("I"=>1,"IL"=>0.5,"LI"=>0.5,"IO"=>0.5,"OI"=>0.5,"IM"=>0.5,"MI"=>0.5,"IU"=>0.5,"UI"=>0.5,"IP"=>0.5,"PI"=>0.5);
	
		$woff_count          = 0;
		$present_count       = 0;
		$late_count          = 0;
		$leave_count         = 0;
		$onduty_count        = 0;
		$holiday_count       = 0;
		foreach ($date_period as $key => $value){
			$att_day  = $value->format('D');
			$att_date = $value->format('Y-m-d');
			$dis_date = $value->format('d-m-Y');
			$desc     = "";
			if($time_rslt[$emp_code][$att_date]['punch_in']){
				$punch_in   		= date("H:i",strtotime($time_rslt[$emp_code][$att_date]['punch_in']));
			}else{
				$punch_in   		= "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['punch_out']){
				$punch_out  		= date("H:i",strtotime($time_rslt[$emp_code][$att_date]['punch_out']));
			}else{
				$punch_out   		= "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['permission_in']){
				$permission_in      = date("H:i",strtotime($time_rslt[$emp_code][$att_date]['permission_in']));
			}else{
				$permission_in   		= "00:00";
			}			
			if($time_rslt[$emp_code][$att_date]['permission_out']){
				$permission_out  	= date("H:i",strtotime($time_rslt[$emp_code][$att_date]['permission_out']));
			}else{
				$permission_out  	= "00:00";
			}
			if($shift_rslt[$emp_code][$att_date]['short_name']){
				$shift_name         = $shift_rslt[$emp_code][$att_date]['short_name'];
			}else{
				$shift_name  		= "";
			}
			if($time_rslt[$emp_code][$att_date]['total_work_hours']){
				$minutes = $time_rslt[$emp_code][$att_date]['total_work_hours'];
				$total_work_hours   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
				// $total_work_hours   = number_format((float)$total_work_hours, 2, '.', '');
			}else{
				$total_work_hours   = "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['total_late_hours']){
				$minutes = $time_rslt[$emp_code][$att_date]['total_late_hours'];
				$total_late_hours   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
				//$total_late_hours   = number_format((float)$total_late_hours, 2, '.', '');
				$late_count = $late_count +1;
			}else{
				$total_late_hours  	= "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['total_excess_hours']){
				$minutes = $time_rslt[$emp_code][$att_date]['total_excess_hours'];
				$total_excess_hours   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
				//$total_excess_hours   = number_format((float)$total_excess_hours, 2, '.', '');
			}else{
				$total_excess_hours = "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['early_out']){
				$minutes = $time_rslt[$emp_code][$att_date]['early_out'];
				$early_out   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
			}else{
				$early_out = "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['late_in']){
				$minutes = $time_rslt[$emp_code][$att_date]['late_in'];
				$late_in   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
			}else{
				$late_in = "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['approved_ot_mins']){
				$minutes = $time_rslt[$emp_code][$att_date]['approved_ot_mins'];
				$approved_ot_mins   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
				//$approved_ot_mins   = number_format((float)$approved_ot_mins, 2, '.', '');
			}else{
				$approved_ot_mins  	= "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['whole_day_status']){ // MODIFIED BY [MS 21-09-2024]
				$whole_day_status   = $time_rslt[$emp_code][$att_date]['whole_day_status'];
				if($present_arr[$whole_day_status]){   // PRESENT
					$present_count = $present_count + $present_arr[$whole_day_status];
				}
				if($leave_arr[$whole_day_status]){     // LEAVE OR ABSENT
					$leave_count = $leave_count + $leave_arr[$whole_day_status];
				}
				if($onduty_arr[$whole_day_status]){ //ONDUTY
					$onduty_count       = $onduty_count + $onduty_arr[$whole_day_status];
					// $present_count      = $onduty_count + $present_arr[$whole_day_status];
				}
				if($mpunch_arr[$whole_day_status]){    // MANUAL PUNCH
					$present_count = $present_count + $mpunch_arr[$whole_day_status];
				}
				if($whole_day_status === "H"){ // HOLIDAY
					$holiday_count          = $holiday_count + 1; 	
				}
				
				if($weekoff_arr[$whole_day_status]){	 // WEEKOFF		    		
					$woff_count             = $woff_count + $weekoff_arr[$whole_day_status];
				} 
				if($unpunch_arr[$whole_day_status]){   // UNPUNCH
					$present_count = $present_count + $unpunch_arr[$whole_day_status];
				}
				if($invalid_arr[$whole_day_status]){   // INVALID 
					$present_count = $present_count + $invalid_arr[$whole_day_status];
				}
			}else
			if($holiday_rslt[$att_date]){
				$woff_count = $woff_count + 1;
				//$whole_day_status   = "H";
			}else
			if($weekoff_rslt[$emp_code][$att_date]){
				$woff_count = $woff_count + 1;
				//$whole_day_status   = "W";
			}else{
				$whole_day_status  	= "-";
			}
			if($time_rslt[$emp_code][$att_date]['total_permission']){
				$minutes            = $time_rslt[$emp_code][$att_date]['total_permission'];
				$total_permission   = sprintf('%02d:%02d', intdiv($minutes, 60), ($minutes % 60));
				// $total_permission   = number_format((float)$total_permission, 2, '.', '');
			}else{
				$total_permission  	= "00:00";
			}
			if($time_rslt[$emp_code][$att_date]['desc']){
				$desc         = $time_rslt[$emp_code][$att_date]['desc'];
			}
			
			$table_arr[$dis_date]   = ['dis_date' => $dis_date, 'att_day' => $att_day, 'punch_in' => $punch_in, 'punch_out' => $punch_out, 'late_in' => $late_in, 'early_out' => $early_out , 'shift_name' => $shift_name, 'total_work_hours' => $total_work_hours, 'total_late_hours' => $total_late_hours,'permission_in' => $permission_in,'permission_out' => $permission_out, 'total_permission' => $total_permission ,'total_excess_hours' => $total_excess_hours , 'approved_ot_mins' => $approved_ot_mins , 'whole_day_status' => $whole_day_status , 'desc' => $desc];
		}
		
		// PERMISSION QRY [MS 10-12-2024]
		$perm_qry      = 'SELECT COUNT(*) as perm_count,SUM(total_minute) AS total_minute  FROM cw_permission_entry WHERE permission_date BETWEEN "'.$salary_start_date.'" and "'.$salary_end_date.'" and employee_code = "'.$emp_code.'" AND trans_status = 1';
		$perm_info     =  $this->runQuery($perm_qry);
		$perm_rslt     = $this->result_array($perm_info);
		$perm_count    = $perm_rslt[0]['perm_count'];
		$emp_data_qry  = 'SELECT employee_code,emp_name,date_of_birth,date_of_joining FROM cw_employees WHERE cw_employees.trans_status = 1 and employee_code = "'.$emp_code.'"';
		$emp_data      = $this->runQuery($emp_data_qry);
		$empresult     = $this->result_array($emp_data);
		$emp_data_rslt = array_reduce($empresult ?? [], function ($result, $arr) {		
			$result[$arr['employee_code']] = $arr;
			return $result;
		}, array());	
		$woff_hday     = $woff_count + $holiday_count;
		$emp_name      = $emp_data_rslt[$emp_code]['emp_name'];
		$department    = $emp_data_rslt[$emp_code]['department'];
		// $company_info  = $this->company_info();
		$time_card_arr = [];
		// $time_card_arr['company_info']  =   $company_info[0];
		$time_card_arr['emp_code']      =   $emp_code;
		$time_card_arr['department']    =   $department;
		$time_card_arr['emp_name']      =   $emp_name;
		$time_card_arr['count_arr']     =   ['present_count' => $present_count,'leave_count' => $leave_count,'onduty_count' => $onduty_count,'woff_hday' => $woff_hday,'late_count' => $late_count , "permission_count" => $perm_count];	
		$time_card_arr['data']			= $table_arr;
		return $time_card_arr;
	}
    # PAYSLIP
    public function payslip($json){
        $this->validate_jwt(); # JWT TOKEN
        $code              = $json->code ?? null;
        $frm_mon           = $json->frmMon ?? null;
        $to_mon            = $json->toMon ?? null;
        $db_name           = $this->database;
        $fromToMonthValid  = $this->fromToMonthValidation($frm_mon,$to_mon,"month");
		if($fromToMonthValid){
			return $this->returnResult(False, 'To Month Must Be Greater Than From Month', [], []);
		}
        if(!$code || !$frm_mon || !$to_mon){
            return $this->returnResult(False, 'Failed - Emp code,process_month required', [], []);
        }
        # PAYSLIP COL BASED GENERATION
        $com_qry           = 'SELECT payslip_based_on,encrypted_pdf FROM cw_company_information WHERE trans_status = 1';
        $com_info          = $this->runQuery($com_qry);
        $com_rslt          = $this->result($com_info);
        $pay_on            = $com_rslt[0]->payslip_based_on;
        $enc_pdf           = (int)$com_rslt[0]->encrypted_pdf;
        if(!$pay_on){
            return $this->returnResult(False, 'Failed - kindly checkout company information', [], []);
        }
        $emp_qry           = 'SELECT '.$pay_on.' FROM cw_employees WHERE trans_status = 1 AND employee_code = "'.$code.'"';
        $emp_info          = $this->runQuery($emp_qry);
        $emp_rslt          = $this->result($emp_info);
        
        if((int)count($emp_rslt ?? []) === (int)0 ){
            return $this->returnResult(True, 'Failed - No Data Found', [], []);
        }
        $pay_id            = $emp_rslt[0]->$pay_on;
        # FORM SETTING
        $form_qry          = 'SELECT prime_module_id,prime_form_id,view_name,label_name,field_type,pick_list_type,pick_list,pick_table,auto_prime_id,auto_dispaly_value FROM cw_form_setting WHERE trans_status = "1" AND prime_module_id = "employees" AND label_name = "'.$pay_on.'" ';
        $form_info         = $this->runQuery($form_qry);
        $form_rslt         = $this->result($form_info);
        $pick_table        = $form_rslt[0]->pick_table;
        $pick_list         = $form_rslt[0]->pick_list;
        if($pick_list && $pick_table){
            $name_qry      = 'SELECT '.$pick_list.' FROM '.$pick_table.' WHERE trans_status = 1';
            $name_info     = $this->runQuery($name_qry);
            $name_rslt     = $this->result($name_info);
            $pick_list_arr = explode(",",$pick_list ?? "");
            $pick_id       = $pick_list_arr[0];
            $pick_name     = $pick_list_arr[1];
            $payslip_arr   = array();
            foreach($name_rslt as $key => $value){
                $payslip_arr[$value->$pick_id] = str_replace(" ", "_", $value->$pick_name);
            }
            $payslip_val   = $payslip_arr[$pay_id]; 
            $pdf_name_qry  = 'select prime_print_info_id,print_info_module_id,print_info_name from cw_print_info where pdf_design_for REGEXP "(^|,)('.$pay_id.')(,|$)" and print_info_module_id = "employees" and print_type = 1 and trans_status = 1';  
            $pdf_name_info = $this->runQuery($pdf_name_qry);
            $pdf_name_rslt = $this->result($pdf_name_info);
            $module_name   = $pdf_name_rslt[0]->print_info_module_id;
            $temp_design   = strtolower(str_replace(' ', '_', $pdf_name_rslt[0]->print_info_name));
            $start         = strtotime(date('Y-m-d', strtotime("01-".$frm_mon)));
            $end           = strtotime(date('Y-m-d', strtotime("01-".$to_mon)));
            $pdf           = '';
            while($start <= $end){
                $payslip_mon       = date('m-Y', $start);
                $payslip_name      = date('F Y', $start);
                if($enc_pdf === 1){
                    $file_name     = $db_name."_".$code."_".$payslip_mon; 
                    $enc_file      = $this->encryptFilename($file_name,$db_name);  
                    $enc_file_name = $enc_file."_".$code;
                }else{
                    $enc_file_name = $code;
                }
				$file_path                    = 'pdf_generation/'.$module_name."/$temp_design/$payslip_mon/".$pay_on."_".strtolower($payslip_val)."/".$enc_file_name.".pdf";
                $filename                     = dirname(__FILE__).$file_path;
                $filename                     = str_replace("api","",$filename);
                if(file_exists($filename)){
                    $filename                 = $this->baseurl($file_path);    
                    $pdf                      = $filename;
                    $pdf_arr[$payslip_mon]    = $pdf;
                }
                $start                        = strtotime("+1 month", $start);
            }
            // $pdf = rtrim($pdf,',');
            if(!$pdf){
                return $this->returnResult(True, 'Failed - No Data Found', [], []);
            }
            return $this->returnResult(True,'Success - payslip generated for the above employees',['files' => $pdf_arr , 'password' => 1], []);
        }else{
            return $this->returnResult(False, 'Failed - kindly checkout company information payslip based col form settings', [], []);
        }
    }

    # CHECK DATE IS HOLIDAY OR NOT
    public function isHoliday($json){
        $this->validate_jwt(); # JWT TOKEN
        $code             = $json->code ?? null;
        $frm_date         = $json->from_date ?? null;
        $to_date          = $json->to_date ?? null;
        $from_date_type   = $json->from_date_type ?? null;
        $to_date_type     = $json->to_date_type ?? null;
        $from             = $json->from ?? null;
        if(!$code || !$frm_date || !$to_date || !$from_date_type || !$to_date_type || !$from){
            return $this->returnResult(False, 'Failed - Employee code,frm,to date required', [], []);
        }
        $fin_info         = $this->get_leave_financial_details();
        $fin_id           = $fin_info[0]->prime_leave_financial_year_id;
        if($from === "from_date_type"){
            $get_year     = date("Y", strtotime($frm_date));
            $get_day      = strtolower(date('D',strtotime($frm_date)));
            $check_date   = $frm_date;
        }else
        if($from === "to_date_type"){
            $get_year     = date("Y", strtotime($to_date));
            $get_day      = strtolower(date('D',strtotime($to_date)));
            $check_date   = $to_date;
        }
        # FORM SETTING
        $form_set_qry     = 'SELECT GROUP_CONCAT(label_name) AS label_name FROM cw_form_setting WHERE prime_module_id = "employees" AND input_view_type IN (1,2) AND field_type = 5 ORDER BY label_name';
        $form_set_info    = $this->runQuery($form_set_qry);
        $form_set_rslt    = $this->result($form_set_info);
        $form_label_name  = $form_set_rslt[0]->label_name; 

        # FORM SETTING LABEL NAME VALUES BASED ON THE EMPLOYEE CODE
        $emp_pick_query   = 'SELECT role as category,'.$form_label_name.',employee_code FROM cw_employees WHERE employee_code = "'. $code .'" AND trans_status = 1';
        $emp_pick_info    = $this->runQuery($emp_pick_query);
        $emp_pick_rlst    = $this->result($emp_pick_info);  
        if(!$emp_pick_rlst){
            return $this->returnResult(False, 'Failed - Unknown Employee code', [], []);
        }
        $emp_pick_arr     = [];
        foreach($emp_pick_rlst as $arr){
            $emp_pick_arr[$arr->employee_code] = $arr;
        }
		
        # GENENRAL SETTING PARAMETER BASED TYPE
        $param_type_qry   = 'SELECT parameter_type,based_on FROM cw_general_setting INNER JOIN cw_parameter_type ON cw_parameter_type.prime_parameter_type_id = cw_general_setting.entry_parameter_type WHERE cw_general_setting.trans_status = 1';
        $param_type_info  = $this->runQuery($param_type_qry);
        $param_type_rslt  = $this->result($param_type_info);
        $param_type_arr   = [];
        foreach($param_type_rslt as $param){
            $param_type_arr[$param->parameter_type] = $param->based_on;
        }
        $week_off_entry   = (int)$param_type_arr['Weekly off Entry'];    
        $holiday_entry    = (int)$param_type_arr['Holiday Entry']; 
		
        # CHECK FRM OR TO DATE IS HOLIDAY OR NOT
        if($holiday_entry === 2){
            $holiday_qry    = 'SELECT label_name,components FROM cw_general_setting INNER JOIN cw_form_setting ON cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 2 AND cw_general_setting.trans_status = 1';
            $holiday_info   = $this->runQuery($holiday_qry);
            $holiday_rslt   = $this->result($holiday_info);
            $hol_label_name = $holiday_rslt[0]->label_name;
            $holid_comp_val = $emp_pick_arr[$code]->$hol_label_name;

            $holiday_qry    = 'SELECT count(*) AS count FROM cw_holiday_entry INNER JOIN cw_holiday_entry_holiday_data ON cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id WHERE FIND_IN_SET("'.$holid_comp_val.'", cw_holiday_entry_holiday_data.component_value) AND cw_holiday_entry.holiday_year = "'.$get_year.'" and (cw_holiday_entry_holiday_data.holiday_date = "'.$frm_date.'" or cw_holiday_entry_holiday_data.holiday_date = "'.$to_date.'") AND cw_holiday_entry.trans_status = 1 AND cw_holiday_entry_holiday_data.trans_status = 1';
            
            $holiday_info   = $this->runQuery($holiday_qry);
            $holiday_result = $this->result($holiday_info);
            $holiday_count  = $holiday_result[0]->count;
            if($holiday_count){
                return $this->returnResult(False, 'Failed - You have chosen a holiday', [], ['from'=>"holiday",'holiday_count' => $holiday_count]);
            }
        }
		
        # CHECK FRM OR TO DATE IS WEEK-OFF OR NOT
		
        if($week_off_entry === 1){
            $weekoff_qry  = 'SELECT employee_code,weekoff_date,weekoff_type from cw_weekoff_import WHERE employee_code = "'. $code .'" and weekoff_date = "'.$check_date.'" and financial_setting_id = '.$fin_id.' and trans_status = 1';
            $weekoff_info = $this->runQuery($weekoff_qry);
            $weekoff_rlst = $this->result($weekoff_info);
            $weekoff_arr  = [];
            foreach($weekoff_rlst as $weekoff){
                $weekoff_arr[$weekoff->employee_code][$weekoff->weekoff_date] = $weekoff->weekoff_type;
            }
            if(!empty($weekoff_arr)){
                if($from === "from_date_type"){
                    $weekoff_date_type = (int)$weekoff_arr[$code][$frm_date];
                    if($weekoff_date_type === 1 || $from_date_type === $weekoff_date_type){
                        return $this->returnResult(False, 'Failed - You have Choosed Weekoff day', [], ['from'=>"weekoff"]);
                    }else
                    if($weekoff_date_type !== 1){
                        if($from_date_type === 1){
                            return $this->returnResult(False, 'Failed - You have Choosed Weekoff day', [], []);
                        }
                    }else{
                        return $this->returnResult(True, 'Success - Proceed', [], []);
                    }
                }else
                if($from === "to_date_type"){
                    $weekoff_date_type  = (int)$weekoff_arr[$code][$to_date];
                    if($weekoff_date_type === 1 || $to_date_type === $weekoff_date_type){
                        return $this->returnResult(False, 'Failed - You have Choosed Weekoff day', [], ['from' => "weekoff"]);
                    }else
                    if($weekoff_date_type !==1){
                        if($to_date_type === 1){
                            return $this->returnResult(False, 'Failed - You have Choosed Weekoff day', [], ['from' => "weekoff"]);
                        }
                    }else{
                        return $this->returnResult(True, 'Success - Proceed', [], []);
                    }
                }
            }else{
                return $this->returnResult(True, 'Success - Proceed', [], []);
            }
        }else{   
			
            # QUERY AND CODE ARE USED FOR GET A WEEK OFF AND HOLIDAY DETAILS
            $week_component_query  = 'SELECT label_name,components FROM cw_general_setting INNER JOIN cw_form_setting ON cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 1 AND cw_general_setting.trans_status = 1';
            $week_component_info   = $this->runQuery($week_component_query);
            $week_component_result = $this->result($week_component_info);
            $week_label_name  = $week_component_result[0]->label_name; 
			
            $week_comp_value  = $emp_pick_arr[$code]->$week_label_name;
			
            $weekoff_qry      = 'SELECT cw_weekoff_entry_weekoff_days_details.weekday,cw_weekoff_entry_weekoff_days_details.first_week,cw_weekoff_entry_weekoff_days_details.second_week,cw_weekoff_entry_weekoff_days_details.third_week,cw_weekoff_entry_weekoff_days_details.fourth_week,cw_weekoff_entry_weekoff_days_details.fifth_week FROM cw_weekoff_entry INNER JOIN cw_weekoff_entry_weekoff_days_details ON cw_weekoff_entry_weekoff_days_details.prime_weekoff_entry_id = cw_weekoff_entry.prime_weekoff_entry_id WHERE FIND_IN_SET("'.$week_comp_value.'", cw_weekoff_entry.component_value) AND (cw_weekoff_entry.from_date <= "'.$frm_date.'" AND cw_weekoff_entry.to_date >= "'.$frm_date.'" or cw_weekoff_entry.from_date <= "'.$to_date.'" AND cw_weekoff_entry.to_date >= "'.$to_date.'") AND cw_weekoff_entry.trans_status = 1 AND cw_weekoff_entry_weekoff_days_details.trans_status = 1';
            $weekoff_info     = $this->runQuery($weekoff_qry);
            $weekoff_result   = $this->result($weekoff_info);
			
            if($weekoff_result){
                $weekoff_rslt = [];
                foreach($weekoff_result as $arr){
                    $weekoff_rslt[$arr->weekday] = $arr;
                }
				
                /* Weekoff - END */
                $days_arr     = array( "sun" => 1,"mon" => 2,"tue" => 3,"wed" => 4,"thu" => 5,"fri" => 6,"sat" => 7);
                $week_arr     = array(1 => "first_week",2 => "second_week",3 => "third_week",4 => "fourth_week",5 => "fifth_week");               
                //Check weekoff day exist
                $day          = $days_arr[$get_day];
                $week_no      = $this->weekOfMonth(strtotime($check_date)); 				
                $week         = $week_arr[$week_no];
                $weekoff_date = $weekoff_rslt[$day]->$week;				
                if($weekoff_date){
                    return $this->returnResult(False, 'Failed - You have Choosed Weekoff day', [], ['from' => "weekoff",'weekoff_type' => $weekoff_date]);
                }else{
                    return $this->returnResult(True, 'Success - Proceed', [], []);
                }
            }else{
                return $this->returnResult(True, 'Success - Proceed', [], []);
            }
        }
    }

    public function weekOfMonth($date){
        //Get the first day of the month.
        $firstOfMonth = strtotime(date("Y-m-01", $date));
        //Apply above formula.
        return $this->weekOfYear($date) - $this->weekOfYear($firstOfMonth) + 1;
    }
	public function weekOfYear($date) {
	    $weekOfYear = intval(date("W", $date));
	    if (date('n', $date) == "1" && $weekOfYear > 51) {
	        // It's the last week of the previos year.
	        $weekOfYear = 0;    
	    }
	    return $weekOfYear;
	}
    # BALANCE LEAVE COUNT 
    public function getLeaveBalance($json){
        $employee_code   = $json->code;
        $leave_type      = $json->leave_type;
        // DB BASED CONDITION PENDING
		$financial_info      = $this->get_leave_financial_details();
		$prime_financial_id  = $financial_info[0]->prime_leave_financial_year_id;

		$leave_name_query  = 'SELECT lower(leave_name) as leave_name,leave_opening from cw_leave_creation WHERE prime_leave_creation_id = "'. $leave_type .'" and trans_status = 1 ';
		$leave_name_info   = $this->runQuery("$leave_name_query");
		$leave_name_rlst   = $this->result_array($leave_name_info);
		$leave_name        = $leave_name_rlst[0]['leave_name'];
		$leave_opening     = $leave_name_rlst[0]['leave_opening'];
		$leave_balance     = 0;
		if((int)$leave_opening === 1){
			$leave_balance_query  = 'SELECT (('.$leave_name.'+'.$leave_name.'_credit)-('.$leave_name.'_debit + used_'.$leave_name.'+ pending_'.$leave_name.'+ encash_'.$leave_name.')) as leave_balance from cw_leave_opening where employee_code = "'.$employee_code.'" and cw_leave_opening.trans_status = 1 and financial_setting_id = "'.$prime_financial_id.'"';
			$leave_balance_info   = $this->runQuery("$leave_balance_query");
			$leave_balance_rlst   = $this->result_array($leave_balance_info);
			$leave_balance        = $leave_balance_rlst[0]['leave_balance'];
		}
		return $this->returnResult(True,'Success',array("leave_balance" => $leave_balance,"leave_opening" =>$leave_opening), []);
    }

    # TIME LOG DATA
    public function timelog($json){
        $validate_jwt  = $this->validate_jwt(); # JWT TOKEN
		$code          = $validate_jwt->code;
        $dev_code      = $json->deviceCode ?? null;
        if($dev_code){
            $today     = date('Y-m-d');
			$prev_day  = date('Y-m-d', strtotime('-1 day', strtotime($today)));
			$next_day  = date('Y-m-d', strtotime('+1 day', strtotime($today)));

			$shift_qry     = 'SELECT in_time,out_time,shift_status FROM cw_shift_master INNER JOIN cw_shift_import on cw_shift_import.shift_name =  cw_shift_master.prime_shift_master_id WHERE employee_code = "'.$code.'" and shift_date = "'.$today.'"';
			$shift_info    = $this->runQuery($shift_qry); 
			$shift_rslt    = $this->result($shift_info);
			
			$shift_status  = $shift_rslt[0]->shift_status;
			$in_time       = $shift_rslt[0]->in_time;
			$out_time      = $shift_rslt[0]->out_time;
			$now           = new DateTime();
			$range_from    = '';
			$range_to      = '';
			
			if ((int)$shift_status === 2) { // Night shift
				// Build shift OUT datetime for today
				$shift_out_today = new DateTime($today . ' ' . $out_time);
				if ($now >= $shift_out_today) {
					// 🔹 Shift still running
					$range_from = $today . ' ' . $in_time;
					$range_to   = $next_day . ' ' . $out_time;
				} else {
					// 🔹 Shift completed
					$range_from = $prev_day . ' ' . $in_time;
					$range_to   = $today    . ' ' . $out_time;
				}
			} else {
				// Day shift
				$range_from = $today . ' ' . $in_time;
				$range_to   = $next_day . ' ' . $out_time;
			}
			
			$tqry = " AND t.log_date BETWEEN '$range_from' AND '$range_to' ";
			$qry  = " AND log_date BETWEEN '$range_from' AND '$range_to' ";
			
            $log_qry   = 'SELECT MIN(log_date) AS in_time ,MAX(log_date) AS out_time,(SELECT d.machine_type FROM cw_time_log t INNER JOIN cw_device d ON d.device_id = t.device_id WHERE t.user_id = "'.$dev_code.'" AND t.trans_status = 1 '.$tqry.' ORDER BY t.log_date DESC LIMIT 1) as machine_type FROM cw_time_log WHERE user_id = "'.$dev_code.'" '.$qry.' AND cw_time_log.trans_status = 1 ';		
            $log_info  = $this->runQuery($log_qry);
            $log_rslt  = $this->result($log_info);
            $in_time   = $log_rslt[0]->in_time; 
            $out_time  = $log_rslt[0]->out_time;
            $machine_type  = $log_rslt[0]->machine_type;

			$time_qry  = 'SELECT IF(CAST(punch_in AS CHAR) = "0000-00-00 00:00:00", "", punch_in),IF(CAST(punch_out AS CHAR) = "0000-00-00 00:00:00", "", punch_out) FROM cw_time_entry WHERE employee_code = "'.$code.'"  AND trans_status = 1 and att_date = "'.$today.'"';
            $time_info = $this->runQuery($time_qry);
            $time_rslt = $this->result($time_info);
			$punch_in  = $time_rslt[0]->punch_in ? : $in_time; 
			$punch_out = $time_rslt[0]->punch_out ? : $out_time; 
			
			$userData = [
				'in_time' => $punch_in ? : '',
				'out_time'=> $punch_out ? : '',
				'machine_type'=> $machine_type ? : ''
			];
			return $this->returnResult(True,'Success - In and Out time',['user_data' => $userData], []);
            // }else{
            //     return $this->returnResult(True,'Failed - No data found',[], []);
            // }
        }else{
			return $this->returnResult(False, 'Failed - Device Code required', [], []);
        }
    }

	# DECLARATION ENTRY
	public function decEntry($json){
		$validate_jwt        = $this->validate_jwt(); # JWT TOKEN
		$today 			     = date('d');
		$user_role           = $validate_jwt->user_right;
		$emp_code            = $json->code;
		$tds_type            = $json->tax_type;
		$effective_month     = $json->eff_month;
		$tax_senior_citizen  = $json->sen_citizen; // 1 => NO  / 2 => YES
		
		# FINANCIAL SETTTING INFO
		$fin_info            = $this->financial_setting_info();
        $fin_set_id          = $fin_info[0]->prime_financial_setting_id;
		$process_month_dt    = "01-".$effective_month;	 

		# COMPANY INFO 
		$company_info        = $this->company_info();
		$dec_lock_date       = $company_info[0]->dec_lock_date;

		if((int)$tds_type === 1){
			$std_deduction   = $fin_info[0]->old_sd;
		}else{
			$std_deduction   = $fin_info[0]->new_sd;
		}		
		
		////////////////////////////////////////////////

		//Check Previous Tax Type
		$section_dec_query = 'SELECT a.income_tax_type FROM cw_declaration_entry as a INNER JOIN (SELECT emp_code, date_format(MAX(str_to_date(CONCAT("01-", effective_month), "%d-%m-%Y")) , "%m-%Y") AS max_date FROM cw_declaration_entry where emp_code = "'.$emp_code.'" and finacial_setting_id = "'.$fin_set_id.'" and date_format(str_to_date(CONCAT("01-", effective_month), "%d-%m-%Y"), "%Y-%m-%d") <= date_format(str_to_date("'.$process_month_dt.'", "%d-%m-%Y"), "%Y-%m-%d") GROUP BY emp_code) as groupedtt ON a.emp_code = groupedtt.emp_code AND a.effective_month = groupedtt.max_date';
		$section_dec_data   = $this->runQuery($section_dec_query);
		$section_dec_result = $this->result_array($section_dec_data);
		$income_tax_type    = $section_dec_result[0]['income_tax_type'] ?? null;
		//get employee lock or unlock based on emp_code 
		$emp_lock_query	='SELECT declaration_lock from cw_employees where employee_code ="'.$emp_code.'"';
		$query_info   	= $this->runQuery($emp_lock_query);
		$dec_lock_result = $this->result($query_info);
		$dec_lock_data = $dec_lock_result[0]->declaration_lock;

		if((int)$user_role !== 1 && (int)$user_role !== 4 && (int)$user_role !== 12){
			if($section_dec_result){
				if((int)$income_tax_type !== (int)$tds_type){
					if((int)$income_tax_type === 1){
						$type = "OLD REGIME";            			
					}else{
						$type = "NEW REGIME";            			
					}
					$this->returnResult(False, "Transaction Already Exist $type ..Income Tax Type Could not Change..!!!", [], ["income_tax_type" => $income_tax_type]);
					exit(0);
				}            	
			}
		}
		//declaration lock employee
		if((int)$dec_lock_data === 1){
			$this->returnResult(False, "Declaration is locked for this employee", [], ["income_tax_type" => $income_tax_type]);
			exit(0);
		}
		$tax_process_exit_qry   = 'select count(*) as rslt_count from cw_tax_calculation where emp_code="'.$emp_code.'" and process_month="'.$effective_month.'" and trans_status =1';
		$tax_process_exit_info   = $this->runQuery($tax_process_exit_qry);
		$tax_process_exit_result = $this->result($tax_process_exit_info);
		$tax_exit_count          = $tax_process_exit_result[0]->rslt_count;
		
		if((int)$tax_exit_count === 1){
			$this->returnResult(False, "Already Tax Proceed, Please Delete the tax process?", [], ["income_tax_type" => $income_tax_type]);
			exit(0);
		}
		//declaration_lock_date condition
		if((int)$dec_lock_date < (int)$today){
			$this->returnResult(False, "Declaration entry is locked in company information!.. Please contact HR!..", [], ["income_tax_type" => $income_tax_type]);
			exit(0);
		}			   

		//if((int)$tds_type === 1){
		$tax_section_qry  = 'select cw_tax_section.tax_section,tax_act_details,tax_subsection_column,cw_tax_sub_section.income_tax_type as income_tax_type  from cw_tax_section inner join cw_tax_sub_section on cw_tax_sub_section.tax_section =cw_tax_section.prime_tax_section_id where cw_tax_sub_section.trans_status = 1 and prime_tax_sub_section_id NOT IN (select tax_sub_section from cw_section_matching where cw_section_matching.trans_status = 1)  and ((cw_tax_sub_section.tax_section = 1 AND bill_required = 1) OR (cw_tax_sub_section.tax_section != 1)) and FIND_IN_SET("'.$tds_type.'",cw_tax_section.income_tax_type) and FIND_IN_SET("'.$tds_type.'",cw_tax_sub_section.income_tax_type) and cw_tax_section.prime_tax_section_id != 2 and cw_tax_sub_section.financial_setting_id = "'.$fin_set_id.'" order by cw_tax_section.tax_order';
		$tax_section_info   = $this->runQuery($tax_section_qry);
		$tax_section_result = $this->result($tax_section_info);

		$process_month_dt            = "01-".$effective_month;
		$collect_dec_entry_qry       = 'SELECT a.* FROM cw_declaration_entry as a INNER JOIN (SELECT emp_code, date_format(MAX(str_to_date(CONCAT("01-", effective_month), "%d-%m-%Y")) , "%m-%Y") AS max_date FROM cw_declaration_entry where emp_code = "'.$emp_code.'" and finacial_setting_id = "'.$fin_set_id.'" and date_format(str_to_date(CONCAT("01-", effective_month), "%d-%m-%Y"), "%Y-%m-%d") <= date_format(str_to_date("'.$process_month_dt.'", "%d-%m-%Y"), "%Y-%m-%d") GROUP BY emp_code) as groupedtt ON a.emp_code = groupedtt.emp_code AND a.effective_month = groupedtt.max_date';
		$collect_dec_entry_info      = $this->runQuery($collect_dec_entry_qry);
		$collect_dec_entry_result    = $this->result($collect_dec_entry_info);

		$table_array                       = array();
		$tr_count                          = 1;
		$table_array['tax_house_rent']     = '';
		$table_array['pan_card_no']        = '';
		$table_array['lendor_pan_card_no'] = '';
		$table_array['childran_elig']      = '';
		foreach($tax_section_result as $tax_rslt){
			$subsection_tax_type     =  explode(",",$tax_rslt->income_tax_type);
			$subsec_column_name      =  $tax_rslt->tax_subsection_column;
			$tax_section_head        =  $tax_rslt->tax_section;
			$tax_subsection_head     =  $tax_rslt->tax_act_details;		
			if($collect_dec_entry_result){
				$subsec_column_val   = $collect_dec_entry_result[0]->$subsec_column_name;
				$tax_house_rent      = $collect_dec_entry_result[0]->tax_house_rent;
				$pan_card_no         = $collect_dec_entry_result[0]->pan_card_no;
				$lendor_pan_card_no  = $collect_dec_entry_result[0]->lendor_pan_card_no;
				$children_elig       = $collect_dec_entry_result[0]->children_elig;
				$tax_senior_citizen  = $collect_dec_entry_result[0]->tax_senior_citizen;
			}else{
				$subsec_column_val   = 0;
				$tax_house_rent      = 0;
				$children_elig       = 0;
				$entry_id            = 0;
				$tax_senior_citizen  = 0;
			}				
			$read = '0';     // 0 => readable
			if($subsec_column_name === 'taxsubsec_8'){
				$subsec_column_val = $std_deduction;
				$read = '1'; // 1 => readonly
			}

			$table_array[$tr_count]['tax_section_head']    = $tax_section_head; 
			$table_array[$tr_count]['tax_subsection_head'] = $tax_subsection_head; 
			$table_array[$tr_count]['subsec_column_name']  = $subsec_column_name; 
			$table_array[$tr_count]['subsec_column_val']   = $subsec_column_val; 
			$table_array[$tr_count]['readonly']            = $read; 
			$tr_count++;
		}
		$table_array['tax_house_rent']     = $tax_house_rent ?? 0;
		$table_array['pan_card_no']        = $pan_card_no ?? 0;
		$table_array['lendor_pan_card_no'] = $lendor_pan_card_no ?? 0;
		$table_array['childran_elig']      = $children_elig ?? 0;
		return $this->returnResult(True, "Please Fill Your Declaration..", ['table_array' => $table_array, 'income_tax_type' => $income_tax_type], []);
	}
	// AR-START DECLARATION INSERT AND UPDATE
	public function decInsert($json){
		$validate_jwt        = $this->validate_jwt();
		$today 			     = date('d');
		$created_on          = date("Y-m-d H:i:s");
		$today 			     = date('d');
		$logged_id           = $validate_jwt->prime_employees_id;		
		$emp_code            = $json->code; 
		$income_tax_type     = $json->income_tax_type; 
		$effective_month     = $json->effective_month;
		$category            = $json->category;
		$data                = $json->data;
		// $proof               = $json->proof;
		// $files               = $json->files;

		// get employee lock or unlock based on emp_code 
		$emp_lock_query  	='SELECT declaration_lock from cw_employees where employee_code ="'.$emp_code.'"';
		$query_info   	    = $this->runQuery($emp_lock_query);
		$dec_lock_result    = $this->result($query_info);
		$dec_lock_data      = $dec_lock_result[0]->declaration_lock;

		//Get current active financial settings
		$fin_info            = $this->financial_setting_info();
		$fin_set_id          = $fin_info[0]->prime_financial_setting_id;
		$pan_amt             = $fin_info[0]->landlord_pan_amt;

		# COMPANY INFO 
		$company_info        = $this->company_info();
		$dec_lock_date       = $company_info[0]->dec_lock_date;
		// print_r($data); die;
		if(!empty($data)){
			// PAN CARD AND LENDOR PAN CARD VALIDATION
			foreach ($data as $item) {
				$tax_house_rent     = $item->tax_house_rent ?? 0 ;
				$pan_card_no        = $item->pan_card_no ?? '0.00';
				$lendor_pan_card_no = $item->lendor_pan_card_no ??' ' ;
				$housing_loan       = $item->taxsubsec_21 ?? '0.00';
				$pan_regex          = "/[A-Z]{5}[0-9]{4}[A-Z]{1}/";
				if(!empty($pan_card_no) && !preg_match($pan_regex, $pan_card_no)){
					$this->returnResult(False, "Please Enter Valid Landlord Pan No", [], []);
					return;
				}
				if((!empty($lendor_pan_card_no) && !preg_match($pan_regex, $lendor_pan_card_no))|| $lendor_pan_card_no == "0"){
					$this->returnResult(false, "Please Enter Valid Lendor Pan No", [], []);
					return;
				}
				if(intval($tax_house_rent) >= intval($pan_amt) && empty($pan_card_no)){
					$this->returnResult(False, "Please Enter Landlord PAN Card No", [], []);
					return;
				}
				if(intval($housing_loan) && empty($lendor_pan_card_no)){
					$this->returnResult(False, "Please Enter Lendor PAN Card No", [], []);
					return;
				}
			}
			$prime_qry_key       = '';
			$prime_qry_value     = '';
			$update_qry_key      = '';
			$update_qry_value    = '';
			$update_upd_query    = '';	
			foreach ($data as $item){
				foreach($item as $column_name => $column_value){
					if($column_name !== "emp_code"){
						$prime_qry_key      .= $column_name . ",";
						$prime_qry_value    .= '"' . $column_value . '",';		
						$update_qry_key     .= $column_name . ",";
						
						$update_qry_value   .= '"' . $column_value . '",';
						$update_upd_query   .= $column_name . ' = "' . $column_value . '",';
					}
					
				}
			}
			//declaration lock employee
			
			if((int)$dec_lock_data === 1){
				$this->returnResult(False, "Declaration is locked for this employee", [], ["income_tax_type" => $income_tax_type]);
				exit(0);
			}
			$tax_process_exit_qry    = 'select count(*) as rslt_count from cw_tax_calculation where emp_code="'.$emp_code.'" and process_month="'.$effective_month.'" and trans_status =1';
			$tax_process_exit_info   = $this->runQuery($tax_process_exit_qry);
			$tax_process_exit_result = $this->result($tax_process_exit_info);
			$tax_exit_count          = $tax_process_exit_result[0]->rslt_count;
			//declaration_lock_date condition
			if((int)$dec_lock_date < (int)$today){
				$this->returnResult(False, "Declaration entry is locked in company information!.. Please contact HR!..", [], ["income_tax_type" => $income_tax_type]);
				exit(0);
			}
			if((int)$tax_exit_count === 1){
				$this->returnResult(False, "Already Tax Proceed, Please Delete the tax process?",[],[]);
				exit(0);
			}else{
				$exit_emp_qry            = 'select count(*) as rslt_count from cw_declaration_entry where finacial_setting_id="'.$fin_set_id.'" and emp_code="'.$emp_code.'" and effective_month="'.$effective_month.'" and trans_status =1';
				$exit_emp_info           = $this->runQuery($exit_emp_qry);
				$exit_emp_result         = $this->result($exit_emp_info);
				$rslt_count              = $exit_emp_result[0]->rslt_count;
				
				if((int)$rslt_count === 0){
					$prime_qry_key           .= "emp_code, finacial_setting_id, trans_created_by, trans_created_date, income_tax_type, effective_month,category ";
					$prime_qry_value         .=' "'.$emp_code.'","'.$fin_set_id.'","'.$logged_id.'", "'.$created_on.'","'.$income_tax_type.'","'. $effective_month .'","'. $category.'"';
					$dec_entry_insert_qry     = "insert into cw_declaration_entry ($prime_qry_key) values ($prime_qry_value)";
					$dec_entry_insert_info    = $this->runQuery($dec_entry_insert_qry);
					$dec_entry_insert_result  = $this->result($dec_entry_insert_info);
					$update_query             = 'UPDATE cw_employees SET income_tax_type = "'.$income_tax_type.'" WHERE employee_code = "'. $emp_code .'"';
					$this->runQuery($update_query);
					$this->returnResult(True,"Successfully added your declaration entry",[],[]);
				}else{
					$update_upd_query     .= 'trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'",category = "'.$category.'"';
					$update_query          = 'UPDATE cw_declaration_entry SET '.$update_upd_query.' WHERE finacial_setting_id = "'. $fin_set_id .'" and emp_code = "'.$emp_code.'" and effective_month = "'.$effective_month.'"';
					// echo $update_query; die;
					$this->runQuery($update_query);
					// $emp_query          = 'UPDATE cw_employees SET income_tax_type = "'.$income_tax_type.'" WHERE employee_code = "'. $emp_code .'"';
					// $this->runQuery($emp_query);
					$this->returnResult(True,"Successfully data is updated!!!",[],[]);
				}	
			}
		}
		// if(!empty($proof)){
		// 	$prime_qry_key       = '';
		// 	$prime_qry_value     = '';
		// 	$update_qry_key      = '';
		// 	$update_qry_value    = '';
		// 	$update_upd_query    = '';
		// 	foreach ($proof as $item){
		// 		foreach($item as $column_name => $column_value){
		// 			if($column_name !== "emp_code"){
		// 				$prime_qry_key      .= $column_name . ",";
		// 				$prime_qry_value    .= '"' . $column_value . '",';		
		// 				$update_qry_key     .= $column_name . ",";
		// 				$update_qry_value   .= '"' . $column_value . '",';
		// 				$update_upd_query   .= $column_name . ' = "' . $column_value . '",';
		// 			}
					
		// 		}
		// 	}
		// 	$exit_proof_qry    = 'select count(*) as rslt_count from cw_tax_proof_entry where finacial_setting_id="'.$fin_set_id.'" and emp_code="'.$emp_code.'" and trans_status =1';
		// 	$exit_proof_info    = $this->runQuery($exit_proof_qry);
		// 	$exit_proof_result  = $this->result($exit_proof_info);
		// 	$rslt_count         = $exit_proof_result[0]->rslt_count;

		// 	if((int)$rslt_count === 0){
		// 		$prime_qry_key              .= "finacial_setting_id,trans_created_by,trans_created_date,emp_code";
		// 		$prime_qry_value            .= '"'.$fin_set_id.'","'.$logged_id.'",'.'"'.$created_on.'",'.'"'.$emp_code.'"';
		// 		$proof_entry_insert_qry      = "insert into cw_tax_proof_entry ($prime_qry_key) values ($prime_qry_value)";
		// 		$proof_entry_insert_info     = $this->runQuery($proof_entry_insert_qry);
		// 		$proof_entry_insert_result   = $this->result($proof_entry_insert_info);
		// 		$this->returnResult(True,"Successfully added your proof entry value",[],[]);
		// 	}else{
		// 		$update_upd_query     .= 'trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'"';
		// 		$update_query          = 'UPDATE cw_tax_proof_entry SET '. $update_upd_query .' WHERE finacial_setting_id = "'. $fin_set_id .'" and emp_code = "'. $emp_code .'"';
		// 		$this->runQuery($update_query);
		// 		$this->returnResult(True,"Successfully proof data is updated!!!",[],[]);
		// 	}
		// }
		// if(!empty($files)){
		// 	foreach($files as $filedata){
		// 		$cal_name  = $filedata->calname;
		// 		$documents = $filedata->documents; 
		// 		foreach($documents as $document){
		// 			$file_path ="./proof_entry/$emp_code/$cal_name/"."ENC_".base64_encode(strtotime(date('d-m-Y H:i')))."ENC_";
		// 			if(!file_exists($file_path)){
		// 				mkdir($file_path, 0777, true);
		// 			}
		// 			$timestamp     = time();
		// 			$act_name      = $document->filename;
		// 			$filename      = "ENC_".base64_encode($timestamp)."ENC_".str_replace(' ', '_', $act_name);
		// 			$uploaded_file = $file_path.$filename;
					

		// 			$file_content = base64_decode($document->content);
		// 			file_put_contents($uploaded_file, $file_content);
		// 			 // Insert into database
		// 			$proof_entry_doc_insert_qry = 'insert into cw_tax_proof_entry_doc (emp_code, fin_set_id, cal_name, file_path, act_file_name, import_name, trans_created_by, trans_created_date) values ("'.$emp_code.'", "'.$fin_set_id.'", "'.$cal_name.'", "'.$file_path.'", "'.$act_name.'", "'.$filename.'", "'.$logged_id.'", "'.$created_on.'")';
		// 			$proof_entry_doc_insert_info     = $this->runQuery($proof_entry_doc_insert_qry);
		// 			$proof_entry_doc_insert_result   = $this->result($proof_entry_doc_insert_info);

		// 		}
		// 	}
		// 	return true;
		// }
	}
	   // AR END

	#  GET FINANCIAL YEAR DETAILS FROM cw_financial_setting
	public function financial_setting_info(){
		$fin_info_qry        = 'SELECT prime_financial_setting_id,start_date,end_date,old_rebate,old_m_relief,new_rebate,new_m_relief,old_sd,new_sd,landlord_pan_amt FROM cw_financial_setting WHERE set_as_default_financial_year = 1 AND trans_status = "1"';
		$fin_info            = $this->runQuery($fin_info_qry);
		$fin_info_rslt       = $this->result($fin_info);
		return $fin_info_rslt;
	}
    # VALIDATION
    public function validations($apidata,$module,$requestType){
		$validation_arr = [];		
        $valid_arr  = array("1" => ["request_type","leave_type","from_date","from_date_type","to_date","to_date_type","no_of_days","reason","cancellation_request"], "3" => ["request_type","from_date","from_date_type","to_date","to_date_type","reason","cancellation_request"] ,"4" => ["request_type","shift_name","permission_type","permission_date","in_time","out_time","total_time","reason","cancellation_request"] , "6" => ["request_type","shift_date","current_shift","change_shift","reason","cancellation_request"],"7" => ["request_type","mp_reason","shift_date","shift_name","in_date","out_date","in_time","out_time","total_time","reason","cancellation_request"], "8" => ["request_type","from_date","from_date_type","to_date","to_date_type","business_file","reason","cancellation_request"]);
		  
		if($requestType){
			$where_cond     = 'AND label_name IN ('."'".implode("','",$valid_arr[$requestType] ?? [])."'".')';
		}else{
			$where_cond     = "and mandatory_field = 1";
		}
		# FORM SETTING
		$form_setting_qry   = 'SELECT view_name, label_name FROM cw_form_setting WHERE trans_status = 1 AND prime_module_id = "request" '.$where_cond;
		$form_setting_info  = $this->runQuery($form_setting_qry);
		$form_setting_rslt  = $this->result_array($form_setting_info);	
		$i = 0;
		//print_r($apidata); die;
		foreach($form_setting_rslt as $key){
			$label_name     = $key['label_name'];
			if(!$apidata->$label_name){
				$validation_arr[$key['label_name']]  = $key['view_name'].' - Required';	
            }
			$i++;
		}
        if($validation_arr){
            if(count($validation_arr ?? []) > 0){
                return $validation_arr;
            }
        }
        $form_qry   = 'SELECT * FROM cw_form_setting WHERE trans_status = 1 AND prime_module_id = "'.$module.'"';
        $form_info  = $this->runQuery($form_qry);
        $form_rslt  = $this->result($form_info);
        $form_arr   = [];
        foreach($form_rslt as $form){
            $form_arr[$form->label_name] = $form;
        }
        if($apidata){
            foreach($apidata as $label => $val){
                $text_type    = (int)$form_arr[$label]->text_type;
                $date_type    = (int)$form_arr[$label]->date_type;
                $field_type   = (int)$form_arr[$label]->field_type;
                $field_length = (int)$form_arr[$label]->field_length;
                $mand_field   = $form_arr[$label]->mandatory_field;
				if($label === 'contact_no'){
					$text_type = 0;
				}
                if($mand_field && empty($val)){
                    $validation_arr[$label] = 'Invalid - Required field';
                    continue;
                }
                if(!empty($val)){
                    switch($field_type){
                        case 1: # TEXT
                            if($text_type === 1 && $this->validateString($val) === 0){
                                $validation_arr[$label] = 'Invalid - Only Alphabets allowed.';
                            }elseif($text_type === 2 && $this->validateDecimal($val) === 0){
                                $validation_arr[$label] = 'Invalid - Only Decimal Values allowed.';
                            }elseif($text_type === 3 && !is_numeric($val)){
                                $validation_arr[$label] = 'Invalid - Only integer allowed.';
                            }elseif($text_type === 1 || $text_type === 2 || $text_type === 3){ 
                                if(strlen($val) > $field_length){
                                    $validation_arr[$label] = "Invalid - provide complete $field_length-digit";
                                }
                            }
                            break;
                        case 2: # DECIMAL
                            if($this->validateDecimal($val) === 0){
                                $validation_arr[$label] = 'Invalid - Only Decimal Values allowed.';
                            }
                        case 3: # INTEGER
                            if(!is_numeric($val)){
                                $validation_arr[$label] = 'Invalid - Only integer allowed.';
                            }
                            break;
                        case 4: # DATE
                            if($date_type === 1 && $this->validateDATE($val) === 0){
                                $validation_arr[$label] = 'Invalid - only format[YYYY-MM-DD] allowed.';
                            }elseif($date_type === 2 && $this->validateMonthYear($val) === 0){
                                $validation_arr[$label] = 'Invalid - only format[MM-YYYY] allowed.';
                            }elseif($date_type === 3 && $this->validateYear($val) === 0){
                                $validation_arr[$label] = 'Invalid - only format[YYYY] allowed.';
                            }
                            break;
                        case 11: # MOBILE NO
                            if((int)$this->validateMobileNumber($val) === 0){
                                $validation_arr[$label] = 'Invalid - Provide valid mobile number';
                            }
                            break;
                        case 12: # EMAIL
                            if(!filter_var($val, FILTER_VALIDATE_EMAIL)){
                                $validation_arr[$label] = 'Invalid - Provide valid Email Id';
                            }
                            break;
                        case 13: # DATE TIME
                            if((int)$this->validateDateTime($val) === 0){
                                $validation_arr[$label] = 'Invalid - only format[HH:MM:SS YYYY-MM-DD] allowed.';
                            }
                            break;
                        case 14: # READONLY
                            if($val){
                                $validation_arr[$label] = 'Invalid - Field is read-only.';
                            }
                            break;
                        // case 15: # TIME
                        //     if((int)$this->validatetime($val) === 0){
                        //         $validation_arr[$label] = 'Invalid - only format[HH:MM:SS] allowed.';
                        //     }
                        //     break;
                    }  
                }  
            }
        }
        return $validation_arr;
    }

    # RETURN RSLT
    public function returnResult($sts, $msg, $rslt, $err){
        if($rslt){
			if(!$err){
				$err = new stdClass();
			}
            $return_data =  json_encode(['sts' => $sts,'msg' => $msg,'rslt' => $rslt,'error' => $err]);
        }else
        if(!$rslt && !$err){
            $rslt = new stdClass();
            $err  = new stdClass();
            $return_data = json_encode(['sts' => $sts,'msg' => $msg,'rslt' => $rslt,'error' => $err]);
        }else{
            $return_data = json_encode(['sts' => $sts,'msg' => $msg,'rslt' => $rslt,'error' => $err]);
        }		
		$key             = 'Aew7^&RS6SFmd9cn'; // Secret key for hash
	    $return_data     = $this->encryptData($return_data,$key);
		echo $return_data;
		exit;
    }

    # ENCRYPTION
    public function encryptData($data,$key){
        # OPEN SSL - AES 256 CBC
        return openssl_encrypt(
            $data,
            'AES-256-CBC',
            hash('sha256', $key),
            0,
            substr(hash('sha256', $key), 0, 16)
        );
    }
	#Decryption
	public function encDec($json){ 
        try {
            // Input data
            $finalEncryptedData = "$json";
            $secretKeyHash = '4kLp9!mZxq8RzLq2'; // Secret key for hash
            $secretKeyAES = 'kD8!fP2#qWz80928'; // AES key (16 bytes)
        
            // Step 1: Decrypt Base64 with Hash
            $aesEncryptedData = $this->decryptBase64WithHash($finalEncryptedData, $secretKeyHash);
        
            // Step 2: Decrypt AES
            $originalData =  $this->decryptAES($aesEncryptedData, $secretKeyAES);
            return $originalData;
        
        } catch (Exception $e) {
            echo json_encode(['sts'  => False,'msg' => $e->getMessage()]);
            exit(0);
        }
    }

    # GET DEFAULT LEAVE FINANCIAL YEAR
    public function get_leave_financial_details(){
        $fin_query  = 'SELECT prime_leave_financial_year_id,starting_date,ending_date from cw_leave_financial_year where set_as_default_financial_year = 1 and trans_status = "1"';
        $fin_data   = $this->runQuery($fin_query);
        $fin_result = $this->result($fin_data);
        return $fin_result;             
    }

    # BASE URL
    public function baseurl($file_path) {
		// Detect protocol
		$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';

		// Use HTTP_HOST (includes port if any)
		$host = $_SERVER['HTTP_HOST']; // example: 124.123.68.45:81 or hrms.allyindian.com

		// Correct directory path
		$dir = rtrim(dirname($_SERVER['REQUEST_URI']), '/');

		// Build base URL
		$baseurl = $protocol . "://" . $host . $dir . '/';

		// Build full file path
		$filename = $baseurl . ltrim($file_path, '/');

		// Remove /api from middle or end
		$filename = str_replace('/api/', '/', $filename);
		$filename = str_replace('/api', '', $filename);

		return $filename;
	}

    # USER ID
    public function primeId($code){
        $emp_qry  = 'SELECT prime_employees_id FROM cw_employees WHERE trans_status = 1 AND employee_code = "'.$code.'" ';
        $emp_info = $this->runQuery($emp_qry);
        $emp_rslt = $this->result($emp_info);
        if(!$emp_rslt){
            return $this->returnResult(False, 'Failed - Invalid Employee code', [], []);
        }
        $prime_id = (int)$emp_rslt[0]->prime_employees_id;
        return $prime_id;
    }

    # RUN QUERY
    public function runQuery($query){
        $result = mysqli_query($this->db,$query);
        if(!$result){
            echo("Error description: ".mysqli_error($this->db)."<br/>");
            return false;
        }else{
            return $result;
        }       
    }

	public function runQuery_insert_id($query) {
		$result    = mysqli_query($this->db,$query);
		$insert_id = $this->db->insert_id;
		if(!$result){
			echo('Error description: '.mysqli_error($this->db).'<br/>');
			return false;
		}else{
			return $insert_id;
		}
	}

    # RESULT AS OBJECT
    public function result($result){
        $data = array();
        while($obj = mysqli_fetch_object($result)){
            if($obj){               
                $data[] = $obj;
            }
        }
        return $data;
    }
    # RESULT AS ASSOCIATIVE ARRAY [MS 23-10-2024]
    public function result_array($result){
        $data = array();
        while($obj = mysqli_fetch_assoc($result)){
            if($obj){               
                $data[] = $obj;
            }
        }
        return $data;
    }

    # TRIGGER SMS
    public function triggersms($mobile_number,$sms_content){
		//Get sms Configuration data
		$sms_content       = urlencode($sms_content);
		$sms_config_query  = 'select sms_url,sms_sender_id,sms_username,sms_password from cw_company_information where trans_status = 1';
		$sms_config_info   = $this->runQuery($sms_config_query);
		$sms_config_result = $this->result($sms_config_info);
		if($sms_config_result){
			$sms_url       = $sms_config_result[0]->sms_url;
			$sms_user      = $sms_config_result[0]->sms_username;
			$sms_pwd       = $sms_config_result[0]->sms_password;
			$sender_id     = $sms_config_result[0]->sms_sender_id;
		}
		$arr			   = array("sms_user" => $sms_user,"sms_pwd" => $sms_pwd,"sender_id" => $sender_id,"mobile_number" => $mobile_number,"sms_content" => $sms_content);
		foreach($arr as $k => $v){
			$pattern       = '/@'.$k.'@/';
			$sms_url       = preg_replace($pattern,$arr[$k].'&',$sms_url);
		}
        $ch = curl_init($sms_url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);
        if($ch){
            return true;
        }       
    }

    # ENCRYPTION
    public function encryptFilename($data,$key){
        $method = 'aes-256-gcm'; 
        $key    = base64_decode( $key );
        $iv     =  openssl_cipher_iv_length($method);
        $tag    = ""; // openssl_encrypt will fill this
        $result = openssl_encrypt( $data , $method , $key , OPENSSL_RAW_DATA , $iv , $tag , "" , 6 );
        $dirty  = array("+", "/", "=");
        $clean  = array("_PLUS_", "_SLASH_", "_EQUALS_");
        return str_replace($dirty, $clean,base64_encode($iv.$tag.$result ));
    }

    # TIME
    public function validatetime($time){
        return preg_match('/^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/', $time) ? 1 : 0;
    }

    # DATE
    public function validateDATE($date){
        return preg_match('/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/', $date) ? 1 : 0;
    }

    # DATETIME
    public function validateDateTime($datetime){
        $dateTimeRegex = '/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) (0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/';
        return preg_match($dateTimeRegex, $datetime) ? 1 : 0;
    }

    # MOBILE NUMBER
    public function validateMobileNumber($number){
        return preg_match('/^[6-9](?!.*(\d)\1{4})\d{9}$/', $number) ? 1 : 0;
    }

    # MONTH YEAR
    public function validateMonthYear($monthyear){
        return preg_match('/^(0[1-9]|1[0-2])\/\d{4}$/', $monthyear) ? 1 : 0;
    }

    # YEAR
    public function validateYear($year){
        return preg_match('/^\d{4}$/', $year) ? 1 : 0;
    }

    # DECIMAL
    public function validateDecimal($input){
        return preg_match('/^\s*[+\-]?\d+\.\d+\s*$/', $input) ? 1 : 0;
    }

    # TEXT
    public function validateString($str){
        return preg_match('/^[a-zA-Z\s.]+$/', $str) ? 1 : 0;
    }


    # CALENDAR PROCESS START #
	public function getCalendarData($json){ //$employee_code,$start_date,$end_date
		$employee_code  = $json->code;
		$start_date     = $json->startDate;
		$end_date       = $json->endDate;
        $action         = 'calendar';
		$get_events     = $this->get_events($employee_code,$start_date,$end_date,$action);
		return $get_events;
	}
	# GET EVENTS FOR CALENDAR
	public function get_events($employee_code,$start_date,$end_date,$action){
		$total_days_arr        = [];
		$leave_arr             = array("L"=>1,"FL"=>0.5,"SL"=>0.5,"LP"=>0.5,"PL"=>0.5,"LM"=>0.5,"ML"=>0.5,"OL"=>0.5,"LO"=>0.5,"LL"=>1,"WL"=>0.5,"LW"=>0.5,"UL"=>0.5,"LU"=>0.5,"IL"=>0.5,"LI"=>0.5);
		$present_arr           = array("P"=>1,"FP"=>0.5,"SP"=>0.5,"LP"=>0.5,"PL"=>0.5,"PM"=>0.5,"MP"=>0.5,"OP"=>0.5,"PO"=>0.5,"PP"=>1,"IP"=>0.5,"PI"=>0.5,"PU"=>0.5,"UP"=>0.5);
		$onduty_arr            = array("O"=>1,"FO"=>0.5,"SO"=>0.5,"OP"=>0.5,"PO"=>0.5,"OM"=>0.5,"MO"=>0.5,"OL"=>0.5,"LO"=>0.5,"OO"=>1,"WO"=>0.5,"OW"=>0.5,"UO"=>0.5,"OU"=>0.5,"IO"=>0.5,"OI"=>0.5);
		$weekoff_arr           = array("W"=>1,"WL"=>0.5,"LW"=>0.5,"WO"=>0.5,"OW"=>0.5,"WM"=>0.5,"MW"=>0.5);
		$unpunch_arr           = array("U"=>1,"UL"=>0.5,"LU"=>0.5,"UO"=>0.5,"OU"=>0.5,"UM"=>0.5,"MU"=>0.5,"UP"=>0.5,"PU"=>0.5,"FP"=>0.5,"SP"=>0.5,"IU"=>0.5,"UI"=>0.5,"FL"=>0.5,"SL"=>0.5);
		$invalid_arr           = array("I"=>1,"IL"=>0.5,"LI"=>0.5,"IO"=>0.5,"OI"=>0.5,"IM"=>0.5,"MI"=>0.5,"IU"=>0.5,"UI"=>0.5,"IP"=>0.5,"PI"=>0.5);
		$holiday_arr           = array("H"=>1,"HL"=>0.5,"LH"=>0.5,"HO"=>0.5,"OH"=>0.5,"HM"=>0.5,"MH"=>0.5);
		# GET TOS MONTH DAY 
		$get_tos_qry           = 'SELECT day_start,day_end,day_conditions FROM cw_tos_month_day WHERE prime_tos_month_day_id = "4" and trans_status = 1';
		$get_tos_info          = $this->runQuery("$get_tos_qry");
		$get_tos_rslt          = $this->result_array($get_tos_info);
		$day_start             = $get_tos_rslt[0]['day_start'];
		$day_end               = $get_tos_rslt[0]['day_end'];
		if(!$day_start){
			$day_start = "01";
		}
		if(!$day_end){
			$day_end = date("t");
		}
		$day_conditions        = $get_tos_rslt[0]['day_conditions'];
		$tos_start_date        = $start_date;
		$tos_end_date          = $end_date;
		// IF DAY START AND DAY END IS EMPTY WILL GET TO PROCESS START DAY AND END DAY _ARN
		if(empty($day_start) && empty($day_end)){
			// Set day_start to "01"
			$day_start = '01';
			// Set day_end to the last day of start_date's month
			$day_end   = date('t', strtotime($start_date));
		}

		if($day_conditions    == 3 ){
			$tos_start_date[8] = "$day_start[0]";
			$tos_start_date[9] = "$day_start[1]";
			$tos_end_date[8]   = "$day_end[0]";
			$tos_end_date[9]   = "$day_end[1]";
			$tos_start_date    = date('Y-m-d',strtotime("$tos_start_date -1 month"));
		}
		if($action == 'calInfo'){ // ONLY FOR CALINFO # PARTICULAR DATE #
			$tos_start_date    = $start_date;
			$tos_end_date      = $end_date;
		}
		# LEAVE ENTRY EVENTS
		$leave_entry_qry       = 'SELECT cw_leave_entry.employee_code,cw_leave_creation.leave_description,cw_leave_entry.leave_date,cw_leave_status.leave_status ,cw_leave_creation.paid_leave,leave_count,cw_leave_entry.trans_created_date FROM cw_leave_entry INNER JOIN cw_leave_creation ON cw_leave_entry.leave_type = cw_leave_creation.prime_leave_creation_id INNER JOIN cw_leave_status ON cw_leave_entry.leave_status = cw_leave_status.prime_leave_status_id  WHERE cw_leave_entry.employee_code = "'.$employee_code.'" AND cw_leave_entry.leave_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" AND cw_leave_entry.trans_status = 1 and cw_leave_entry.leave_status = 2';
		$leave_entry_info      = $this->runQuery("$leave_entry_qry");
		$leave_entry_rslt      = $this->result_array($leave_entry_info);
		$paid_count        = 0;
		$lop_count         = 0;
		foreach ($leave_entry_rslt as $key => $value) {
			$leave_count   = $value['leave_count'];
			$paid_leave    = $value['paid_leave'];
			if((int)$paid_leave === 1){
				$paid_count += $leave_count;
			}else{
				$lop_count += $leave_count;
			}		
		}
		// TOTAL LATE HOURS
		$late_qry              = 'SELECT SUM(total_late_hours) as late_hours,SUM(approved_ot_mins) as ot_hours,COUNT(CASE WHEN approved_ot_mins > 0 then 1 ELSE NULL END) as ot_count FROM cw_time_entry  WHERE employee_code = "'.$employee_code.'" AND att_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" and trans_status = 1';
		$late_info             = $this->runQuery("$late_qry");
		$late_rslt             = $this->result_array($late_info);
		$late_hours		       = $this->hours_mins_cal($late_rslt[0]['late_hours']);
		$ot_hours		       = $this->hours_mins_cal($late_rslt[0]['ot_hours']);
		$ot_count		       = (int)$late_rslt[0]['ot_count'];
		// PERMISSION BASED QUERY
		$perm_qry              = 'SELECT SUM(total_minute) as total_permission , COUNT(*) AS perm_count FROM cw_permission_entry WHERE employee_code = "'.$employee_code.'" AND permission_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" and trans_status = 1';
		$perm_info             = $this->runQuery("$perm_qry");
		$perm_rslt             = $this->result_array($perm_info);
		$perm_minute           = (int)$perm_rslt[0]['total_permission'];
		$perm_count            = (int)$perm_rslt[0]['perm_count'];
		$perm_hours            =  $this->hours_mins_cal($perm_minute);
		// COUNT BASED ON TOS MONTH DAY
		$get_count_qry         = 'SELECT * FROM cw_time_entry WHERE employee_code = "'.$employee_code.'" AND att_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" and trans_status = 1 GROUP BY att_date'; 
		
  		$get_count_info        = $this->runQuery("$get_count_qry");
		$get_count_rslt        = $this->result_array($get_count_info);
		$holiday_work_count    = 0;
		$woff_work_count       = 0;
		foreach($get_count_rslt as $key => $val){
			if($val['whole_day_status']){	
				$whole_day_status = $val['whole_day_status'];
				$total_work_hours = $val['total_work_hours'];
				if($present_arr[$whole_day_status]){
                   // $total_days_arr['P'] ;
					$total_days_arr['P'] += $present_arr[$whole_day_status];
				}
				if($leave_arr[$whole_day_status]){
					$total_days_arr['L'] += $leave_arr[$whole_day_status];
				}
				if($onduty_arr[$whole_day_status]){
					$total_days_arr['O'] += $onduty_arr[$whole_day_status];
				}
				if($weekoff_arr[$whole_day_status]){
					$total_days_arr['W'] += $weekoff_arr[$whole_day_status];
				}
				if($unpunch_arr[$whole_day_status]){
					$total_days_arr['U'] += $unpunch_arr[$whole_day_status];
				}
				if($invalid_arr[$whole_day_status]){
					$total_days_arr['I'] += $invalid_arr[$whole_day_status];
				}
				if($holiday_arr[$whole_day_status]){
					$total_days_arr['H'] += $holiday_arr[$whole_day_status];
				}
				if($whole_day_status === "H" && (int)$total_work_hours > 0){
					$holiday_work_count       = $holiday_work_count + 1; 	
				}
				if($whole_day_status === "W" && (int)$total_work_hours > 0){
					$woff_work_count          = $woff_work_count + 1;
				}
			}
		}
		$total_days_arr['T']   = count($get_count_rslt ?? []); // TOTAL COUNT
		$present_days          = $total_days_arr['P'] > 0 ? $total_days_arr['P'] : 0;
		$leave_days            = $total_days_arr['L'] > 0 ? $total_days_arr['L'] : 0;
		$absent_days           = $total_days_arr['U'] > 0 ? $total_days_arr['U'] : 0;
		$weekoff_days          = $total_days_arr['W'] > 0 ? $total_days_arr['W'] : 0;
		$onduty_days           = $total_days_arr['O'] > 0 ? $total_days_arr['O'] : 0;
		$invalid_days          = $total_days_arr['I'] > 0 ? $total_days_arr['I'] : 0;
		$holiday_days          = $total_days_arr['H'] > 0 ? $total_days_arr['H'] : 0;
		$total_days            = $total_days_arr['T'] > 0 ? $total_days_arr['T'] : 0;
		$holiday_work_count    = $holiday_work_count  > 0 ? $holiday_work_count : 0;
		
		# GET LEGEND DETAILS 
		$month_info_arr   = array('total_days' => array("title" => "Total Days","value" => $total_days." Days","colour" => "0xffA52A2A"),
		'present'         => array("title"    => "Present","value" => $present_days." Days","colour" => "0xffe5439312"),
		'onduty'          => array("title" => "Onduty","value" => $onduty_days." Days","colour" => "0xffe5439312"),
		'paid_leave'      => array("title" => "Paid Leave","value" => $paid_count." Days","colour" => "0xffFF0000"),
		'lop_count'       => array("title" => "Lop Count","value" => $lop_count + $absent_days." Days","colour" => "0xffFF0000"),
		'invalid'         => array("title" => "Invalid","value" => $invalid_days." Days","colour" => "0xffFF0000"),
		'holiday'         => array("title" => "Holiday","value" => $holiday_days." Days","colour" => "0xffFF69B4"),
		'weekoff'         => array("title" => "Weekoff","value" => $weekoff_days." Days","colour" => "0xffe7ff4500"),		
		'perm_hours'      => array("title" => "Perm Hrs","value" => $perm_hours,"colour" => "0xfffDDA0D"),
		'hday_worked'     => array("title" => "Hday Worked","value" => $holiday_work_count." Days","colour" => "0xffFF69B4"),
		'woff_worked'     => array("title" => "Woff Worked","value" => $woff_work_count." Days","colour" => "0xffe7ff4500"),
		'perm_count'      => array("title" => "Perm Nos","value" => $perm_count,"colour" => "0xfffDDA0D"),
		'late_hours'      => array("title" => "Late Hrs","value" => $late_hours,"colour" => "0xff008080"),
		'ot_hours'        => array("title" => "Ot Hrs","value" => $ot_hours,"colour" => "0xffA52A2A"),
		'ot_count'        => array("title" => "Ot Nos","value" => $ot_count,"colour" => "0xffA52A2A")); //  'absent_days' => $absent_days,		

		$legend_status_qry     = 'SELECT legends,day_description FROM cw_day_status_legends WHERE trans_status = 1';
		$legend_status_info    = $this->runQuery("$legend_status_qry");
		$legend_status_rslt    = $this->result($legend_status_info);
		$legend_arr            = [];
		foreach($legend_status_rslt as $val){
			$legend_arr[$val->legends] = $val->day_description;
		}
		

		if($action != 'calInfo'){ // BECAUSE NO NEED OF TIME ENTRY RESULT
			# TIME ENTRY EVENTS
			$time_entry_qry        = 'SELECT employee_code,cw_day_status_legends.day_description,att_date,DATE_FORMAT(cw_time_entry.punch_in, "%H:%i") AS punch_in,DATE_FORMAT(cw_time_entry.punch_out, "%H:%i") AS punch_out,IF(cw_time_entry.early_in > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.early_in/60),":",LPAD(MOD(cw_time_entry.early_in,60),2,"0")),"%H:%i"), cw_time_entry.early_in) AS early_in,IF(cw_time_entry.excess_out > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.excess_out/60),":",LPAD(MOD(cw_time_entry.excess_out,60),2,"0")),"%H:%i"), cw_time_entry.excess_out) AS excess_out,IF(cw_time_entry.total_excess_hours > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.total_excess_hours/60),":",LPAD(MOD(cw_time_entry.total_excess_hours,60),2,"0")),"%H:%i"), cw_time_entry.total_excess_hours) AS eligible_ot,whole_day_status,cw_shift_master.shift_name,cw_shift_master.from_time,cw_shift_master.to_time,first_half_status,first_half_count,second_half_status,second_half_count,permission_in,permission_out,TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.final_total_work_hours/60),":",LPAD(MOD(cw_time_entry.final_total_work_hours,60),2,"0")),"%H:%i") AS final_total_work_hours,total_permission FROM cw_time_entry INNER JOIN cw_shift_master ON cw_shift_master.prime_shift_master_id = cw_time_entry.shift_id LEFT JOIN cw_day_status_legends ON cw_time_entry.whole_day_status = cw_day_status_legends.legends WHERE employee_code = "'.$employee_code.'" AND att_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" AND cw_time_entry.trans_status = 1 GROUP BY att_date';
			$time_entry_info       = $this->runQuery("$time_entry_qry");
			$time_entry_rslt       = $this->result_array($time_entry_info);
			$base_url 			   = "http://".$_SERVER['SERVER_NAME'].dirname($_SERVER["REQUEST_URI"].'?').'/request';
			$base_url 			   = str_replace("app","index.php",$base_url);
		}
	
		# PERMISSION ENTRY EVENTS
		$perm_entry_qry        = 'SELECT cw_permission_entry.permission_date,cw_permission_type.permission_type,cw_permission_entry.in_time,cw_permission_entry.out_time,cw_permission_entry.total_time,cw_permission_entry.trans_created_date,cw_leave_status.leave_status FROM cw_permission_entry INNER JOIN cw_permission_type ON cw_permission_entry.permission_type = cw_permission_type.prime_permission_type_id INNER JOIN cw_leave_status ON cw_permission_entry.leave_status = cw_leave_status.prime_leave_status_id WHERE cw_permission_entry.employee_code     = "'.$employee_code.'" AND cw_permission_entry.permission_date BETWEEN "'.$tos_start_date.'" AND "'.$tos_end_date.'" and cw_permission_entry.trans_status = 1';
		$perm_entry_info       = $this->runQuery("$perm_entry_qry");
		$perm_entry_rslt       = $this->result_array($perm_entry_info);
		
		# ONDUTY ENTRY EVENTS
		$onduty_entry_qry      = 'SELECT cw_on_duty_entry.on_duty_date,cw_on_duty_entry.on_duty_count,cw_leave_status.leave_status,cw_on_duty_entry.trans_created_date FROM cw_on_duty_entry INNER JOIN cw_leave_status ON cw_on_duty_entry.on_duty_status = cw_leave_status.prime_leave_status_id WHERE employee_code = "'.$employee_code.'" and on_duty_date BETWEEN "'.$tos_start_date.'" and "'.$tos_end_date.'" and cw_on_duty_entry.trans_status = 1';
		$onduty_entry_info     = $this->runQuery("$onduty_entry_qry");
		$onduty_entry_rslt     = $this->result_array($onduty_entry_info);

		# OVERTIME ENTRY
		$overtime_entry_qry    = 'SELECT cw_overtime_entry.entry_date,cw_overtime_entry.ot_in_time,cw_overtime_entry.ot_out_time,cw_overtime_entry.excess_work,cw_leave_status.leave_status,cw_overtime_entry.trans_created_date FROM cw_overtime_entry INNER JOIN cw_leave_status ON cw_overtime_entry.approval_status      = cw_leave_status.prime_leave_status_id WHERE cw_overtime_entry.employee_code = "'.$employee_code.'" and cw_overtime_entry.entry_date BETWEEN "'.$tos_start_date.'" and "'.$tos_end_date.'" and cw_overtime_entry.trans_status = 1';
		$overtime_entry_info   =  $this->runQuery("$overtime_entry_qry");
		$overtime_entry_rslt   = $this->result_array($overtime_entry_info);

		# MANUAL PUNCH ENTRY
		$manual_punch_qry      = 'SELECT cw_manual_punch_entry.in_date,cw_manual_punch_entry.in_time,cw_manual_punch_entry.out_time,cw_leave_status.leave_status,cw_manual_punch_entry.trans_created_date FROM cw_manual_punch_entry INNER JOIN cw_leave_status ON cw_manual_punch_entry.leave_status = cw_leave_status.prime_leave_status_id WHERE cw_manual_punch_entry.employee_code = "'.$employee_code.'" and cw_manual_punch_entry.in_date BETWEEN "'.$tos_start_date.'" and "'.$tos_end_date.'" and cw_manual_punch_entry.trans_status = 1';
		$manual_punch_info     =  $this->runQuery("$manual_punch_qry");
		$manual_punch_rslt     = $this->result_array($manual_punch_info);
	
		// GET LEAVE BALANCE DETAILS
		$leave_bal_arr         = $this->view_leave_details($employee_code,"calendar");
		$api_events_arr        = array('time_entry' => $time_entry_rslt,'leave_entry' => $leave_entry_rslt,'permission_entry' => $perm_entry_rslt,'onduty_entry' => $onduty_entry_rslt,'overtime_entry' => $overtime_entry_rslt,'manual_punch_entry' => $manual_punch_rslt);
        $fy_start_date         = $leave_bal_arr['fy_arr']['fy_starting_date'];
        $fy_end_date           = $leave_bal_arr['fy_arr']['fy_ending_date'];
        $tos_days_arr          = array('tos_start_day' => $day_start , 'tos_end_day' => $day_end , 'fy_start_date' => $fy_start_date , 'fy_end_date' => $fy_end_date);
        if($action === 'calendar'){
            return $this->returnResult(True,'Success - Calendar details',['tos_days_info' => $tos_days_arr ,'month_info' => $month_info_arr ,'leave_bal_info' => $leave_bal_arr,'events_info' => $api_events_arr ,'leave' => $leave_entry_rslt,'permission' => $perm_entry_rslt,'onduty' => $onduty_entry_rslt,'overtime' => $overtime_entry_rslt,'manual_punch' => $manual_punch_rslt], []);
        }else
		if($action === 'calInfo'){
			$leave_entry_rslt['color']    = '0xffFF0000';
			$perm_entry_rslt['color']     = '0xfffDDA0D';
			$onduty_entry_rslt['color']   = '0xffe5439312';
			$overtime_entry_rslt['color'] = '0xffff00e0';
			$manual_punch_rslt['color']   = '0xfff70b38';
			$cal_info_arr                 = [];
			$total_array                  = ['leave' => $leave_entry_rslt,'permission' => $perm_entry_rslt,'onduty' => $onduty_entry_rslt,'manual_punch' => $manual_punch_rslt]; // 'overtime' => $overtime_entry_rslt,

			// FOR DIFFERENT DATE NAME 
			$key_value_arr                = ['leave' => ['date' => 'leave_date'],'permission' => ['date' => 'permission_date'],'onduty' => ['date' => 'on_duty_date'],'overtime' => ['date' => 'entry_date'],'manual_punch' => ['date' => 'in_date']];
			$i = 0;
			foreach ($total_array as $key => $value) {
				foreach ($value as $val) {
					if($val['trans_created_date'] ?? 0 ){
						$color = $total_array[$key]['color'];
						$cal_info_arr[$i]['type']   = ucwords(str_replace('_',' ',$key));
						$cal_info_arr[$i]['date']   = $val[$key_value_arr[$key]['date']];
						$cal_info_arr[$i]['status'] = $val['leave_status'];
						$cal_info_arr[$i]['color']  = $color;
						$cal_info_arr[$i]['t_date'] = $val['trans_created_date'];
						if($key === 'permission'){
							$cal_info_arr[$i]['in_time']    = $val['in_time'];
							$cal_info_arr[$i]['out_time']   = $val['out_time'];
							$cal_info_arr[$i]['total_time'] = $val['total_time'];
						}
						$i++;
					}
				}
			}
			return $this->returnResult(True,'Success - Messeage',['data' => $cal_info_arr], []);
		}else{
            $rslt              = ['leave' => $leave_entry_rslt,'permission' => $perm_entry_rslt,'onduty' => $onduty_entry_rslt,'manual_punch' => $manual_punch_rslt , 'overtime' => $overtime_entry_rslt,];
            return $rslt;
        }
	}	
	# GET LEAVE BALANCE DETAILS
	public function view_leave_details($emp_code,$action){
		$financial_info         = $this->get_leave_financial_details();
		$leave_fin_year_id      = $financial_info[0]->prime_leave_financial_year_id;
		$fy_starting_date       = $financial_info[0]->starting_date;
		$fy_ending_date         = $financial_info[0]->ending_date;
		$leave_qry 				= 'select cw_leave_opening.*,cw_employees.emp_name from cw_leave_opening inner join cw_employees on cw_employees.employee_code = cw_leave_opening.employee_code where cw_leave_opening.employee_code = "'.$emp_code.'" and cw_leave_opening.trans_status = 1 and financial_setting_id = "'.$leave_fin_year_id.'"';
		$leave_info       		= $this->runQuery($leave_qry);
		$leave_result  			= $this->result_array($leave_info);
		
		$leave_creation_qry 	= 'select prime_leave_creation_id,cw_leave_creation.leave_description,cw_leave_creation.leave_name from cw_leave_creation where cw_leave_creation.trans_status = 1 and leave_opening = 1';
		$leave_creation_info    = $this->runQuery($leave_creation_qry);
		$leave_creation_result  = $this->result_array($leave_creation_info);
        $leave_bal_arr          = array();
        foreach($leave_creation_result as $leave_type){
            $leave_name        = strtolower($leave_type['leave_name']);
            $prime_id          = $leave_type['prime_leave_creation_id'];
            $leave_description = ucwords(strtolower($leave_type['leave_description']));
            foreach($leave_result as $key => $val){
                $credit        = $val[$leave_name."_credit"];
                $debit         = $val[$leave_name."_debit"];
                $used          = $val["used_".$leave_name];
                $pending       = $val["pending_".$leave_name];
                $encash        = $val["encash_".$leave_name];

                $total         = $credit + $val[$leave_name];
                $bal_used      = $used   + $pending; 
                $balance       = $total  - $bal_used - $debit -$encash;
            }
            if($action === "calendar"){
                $leave_bal_arr[$leave_name]        =  array('credit' => $credit, 'debit' => $debit, 'used' => $used, 'pending' => $pending, 'encash' => $encash, 'balance' => $balance);
            }else{
                $leave_bal_arr[$leave_description] =  array('prime_id' => $prime_id , 'total' => number_format($total,2), 'debit' => $debit, 'used' => $used, 'pending' => $pending, 'encash' => $encash, 'balance' => number_format($balance,2));
            }
        }
        if($action === "calendar"){
            $fy_arr = array('fy_starting_date' => $fy_starting_date , 'fy_ending_date' => $fy_ending_date);
			$leave_bal_arr['fy_arr'] = $fy_arr;
        }
		return $leave_bal_arr;
	}

    # STATIC VALIDATION
    public function static_validation($json){		
        $validation_arr       = array();
		$pass_arr             = array("curPass" => "Current Password","newPass" => "New Password","conPass" => "Confirm Password");
        if(!$json->frm){
            $validation_arr['frm'] = "frm Is Required";
        }
        foreach($json as $key => $val){
            if($key !== 'frm'){
                if(!$val){
					if(in_array($pass_arr[$key] , $pass_arr)){
						$validation_arr[$key] = $pass_arr[$key]." Is Required";
					}else{	
						if($key !== "leave_balance"){
							$validation_arr[$key] = "$key Is Required..";
						}
						
					}
                }
            }
        }
        if(count($validation_arr ?? []) > 0){
            return $this->returnResult(False, 'Validation Failed', [], $validation_arr);
        }
    }

    # SEARCH LOAN [MS 12-11-2024]
    public function searchLoan($json){
        $employee_code  = $json->code;
        $loan_qry       = 'SELECT cw_loan.*, (SELECT COUNT(*) FROM cw_loan_installment WHERE paid_status = 1 AND loan_id = cw_loan.prime_loan_id) AS
        installment_count,cw_form_setting.view_name FROM cw_loan INNER JOIN cw_form_setting ON cw_loan.loan_type = cw_form_setting.label_name WHERE emp_code = "'.$employee_code.'" AND cw_loan.trans_status = 1 AND cw_form_setting.loan_check = 1 ';
        $loan_info      = $this->runQuery($loan_qry);
		$loan_rslt      = $this->result_array($loan_info);
        //if(count($loan_rslt) > 0){
            return $this->returnResult(True,'Success',array("loan_data" => $loan_rslt), []);
        // }else{
        //     $validation_arr['No data']   = 'No data Found' ;
        //     return $this->returnResult(True,'Failed', [], $validation_arr);
        // }
    }

    # SHIFT CHANGE [MS 19-11-2024] 
    public function shiftChange($json){
        $employee_code       = $json->code;
        $shift_date          = $json->shift_date;
        $db_name             = $this->database;
        // DB BASED CONDITION PENDING
		$financial_info      = $this->get_leave_financial_details();
		$financial_year_id   = $financial_info[0]->prime_leave_financial_year_id; 
        $financial_year_id   = 2 ; // FOR CHECKING PURPOSE
		$shift_import_qry    = 'SELECT shift_name FROM cw_shift_import WHERE cw_shift_import.employee_code = "'.$employee_code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.financial_setting_id= "'.$financial_year_id.'" and cw_shift_import.trans_status = 1';
		$shift_import_info   = $this->runQuery("$shift_import_qry");
		$shift_import_rslt   = $this->result_array($shift_import_info);
		$shift_name          = $shift_import_rslt[0]['shift_name'];	

		if($shift_name){
            return $this->returnResult(True,'Success',array("shift_name" => $shift_name), []);
		}else{
			return $this->returnResult(false,'No Shift Available',array("shift_name" => ''), []);
		}
    }

    # VIEW LEAVE STATUS [MS 19-11-2024] 
    public function leaveStatus($json){
        $employee_code       = $json->code;
        $request_type        = $json->request_type;
		$leave_type          = $json->leave_type;
		$from_date           = $json->from_date;
		$to_date             = $json->to_date;
		$from_date_type      = $json->from_date_type;
		$to_date_type        = $json->to_date_type;
		$leave_balance       = $json->leave_balance;
        
        //
        // $same_date = 0;
		// if($from_date === $to_date){
		// 	$same_date = 1;
		// }
		$financial_info        = $this->get_leave_financial_details();
		$prime_financial_id    = $financial_info[0]->prime_leave_financial_year_id;
		//
		$get_emp_query         = 'SELECT role from cw_employees WHERE employee_code = "'. $employee_code .'" and trans_status = 1';
		$get_emp_info          = $this->runQuery("$get_emp_query");
		$get_emp_rlst          = $this->result_array($get_emp_info);
		$emp_category          = $get_emp_rlst[0]['role'];
		$from_month            = date("m-Y",strtotime($from_date));
		$to_month              = date("m-Y",strtotime($to_date));
		$leave_export_query    = 'SELECT process_month from cw_leave_export WHERE category = "'. $emp_category .'" and trans_status = 1';
		$leave_export_info     = $this->runQuery("$leave_export_query");
		$leave_export_rlst     = $this->result_array($leave_export_info);

		$leave_export_arr      = array_reduce($leave_export_rlst ?? [], function($result, $arr){			
	    	$result[$arr['process_month']] = $arr;
	    	return $result;
		}, array());
		//SAME LEAVE TYPE ALREADY EXIST 
		if((int)$request_type === 1){ //LEAVE REQUEST
			$from_leave_exist_qry  = 'SELECT count(*) as from_exist_count  from cw_leave_entry WHERE employee_code = "'. $employee_code .'" and leave_date = "'.$from_date.'" and financial_setting_id = '.$prime_financial_id.' and leave_status not in (3,4) and leave_type = '.$leave_type.' and trans_status = 1';
			$frm_leave_exist_info  = $this->runQuery("$from_leave_exist_qry");
			$frm_leave_exist_rslt  = $this->result_array($frm_leave_exist_info);

			$to_leave_exist_qry  = 'SELECT count(*) as to_exist_count  from cw_leave_entry WHERE employee_code = "'. $employee_code .'" and leave_date = "'.$to_date.'" and financial_setting_id = '.$prime_financial_id.' and leave_status not in (3,4) and leave_type = '.$leave_type.' and trans_status = 1';
			$to_leave_exist_info      = $this->runQuery("$to_leave_exist_qry");
			$to_leave_exist_rslt      = $this->result_array($to_leave_exist_info);
			$from_exist_rslt  = (int)$frm_leave_exist_rslt[0]['from_exist_count'];
			$to_exist_rslt    = (int)$to_leave_exist_rslt[0]['to_exist_count'];
			if($from_exist_rslt  > 0 || $to_exist_rslt > 0){
                return $this->returnResult(FALSE,'Same Leave type Already Exist for this given Date...!',array("leave_count" => ""), []);
			}
		}
		
		if((int)$request_type === 3){  //ON DUTY 
			$frm_date          = date('Y-m-d',strtotime($from_date));
			$end_date          = date('Y-m-d',strtotime($to_date));
			$on_duty_chk_qry   = 'SELECT COUNT(*) AS count FROM cw_on_duty_entry WHERE employee_code = "'.$employee_code.'" and date_format(str_to_date(on_duty_date, "%Y-%m-%d"),"%Y-%m-%d") between ("'.$frm_date.'") and ("'.$end_date.'") AND on_duty_status IN(1,2) AND trans_status=1';
			$on_duty_info      = $this->runQuery("$on_duty_chk_qry");
			$on_duty_rslt      = $this->result_array($on_duty_info);
			if((int)$on_duty_rslt[0]->count > 0){
                return $this->returnResult(True,'Already On Duty Applied For This Date...',[], []);
			}
		}

		if($leave_export_arr){
			$month_day_result      = $this->tos_day_qry_fun("Leave Entry");
	        $check_leave_month     = "";
			if($month_day_result){
				$day_conditions    = $month_day_result[0]->day_conditions;
				$day_count         = $month_day_result[0]->day_count;
				$day_start         = $month_day_result[0]->day_start;
				$day_end           = $month_day_result[0]->day_end;
				$cur_month         = date('m-Y');
				$leave_from_date   = date("Y-m-d",strtotime($from_date));
				$leave_to_date     = date("Y-m-d",strtotime($to_date));
				$check_leave_arr= array();
				if((int)$day_conditions === 3){
					$sal_start = $day_start;
					//For Current month between days increment
					$date = new DateTime("01-$cur_month 00:00:00");
					$date->modify('-1 month');
					$salary_start_date   = $date->format("Y-m-$sal_start");	
					$salary_end_date     = date("Y-m-d",strtotime($day_end."-".$cur_month));

					if(($leave_from_date >= $salary_start_date) && ($leave_from_date <= $salary_end_date)
						&& ($leave_to_date >= $salary_start_date) && ($leave_to_date <= $salary_end_date)){
						$check_leave_month   = date('m-Y',strtotime($salary_end_date));
					}else
					if($salary_start_date <= $leave_from_date && $salary_end_date >= $leave_from_date && $salary_end_date < $leave_to_date){
						$check_leave_month   = date('m-Y',strtotime($salary_end_date));
					}else
					if($salary_start_date > $leave_from_date){
						$check_leave_month   = date('m-Y',strtotime($salary_start_date));
					}else
					if($salary_end_date < $leave_from_date){
						$check_leave_month   = date('m-Y',strtotime("+1 month",strtotime($salary_end_date)));
					}
				}else{
					$sal_start = '01';
					$date = new DateTime("01-$cur_month 00:00:00");
					$salary_start_date = $date->format("Y-m-$sal_start");	
					$salary_end_date   = date("Y-m-d",strtotime($day_end."-".$cur_month));

					if($salary_start_date <= $leave_from_date && $salary_end_date >= $leave_from_date && $salary_start_date <= $leave_to_date && $salary_end_date >= $leave_to_date){
						$check_leave_month  = date('m-Y',strtotime($salary_start_date));
					}else
					if($salary_start_date <= $from_date && $salary_end_date >= $from_date && $salary_end_date < $leave_to_date){
						$check_leave_month  = date('m-Y',strtotime($salary_end_date));
					}else
					if($salary_start_date > $leave_from_date){
						$check_leave_month  =  date('m-Y',strtotime("-1 month",strtotime($salary_end_date)));
					}else
					if($salary_end_date < $leave_from_date){
						$check_leave_month  =  date('m-Y',strtotime("+1 month",strtotime($salary_end_date)));
					}
				}
				if($check_leave_month){
					if(array_key_exists($check_leave_month,$leave_export_arr ?? [])){
                        return $this->returnResult(True,"Don't Leave Applied",[], []);
					}
				}
			}
		}
		$check_leave_query   = 'SELECT leave_date,leave_count,leave_type from cw_leave_entry WHERE employee_code = "'. $employee_code .'" and leave_date between "'.$from_date.'" and "'.$to_date.'" and financial_setting_id = '.$prime_financial_id.' and leave_status not in (3,4) and trans_status = 1';
		$check_leave_info   = $this->runQuery("$check_leave_query");
		$check_leave_rlst   = $this->result_array($check_leave_info);
		//FROM ON DUTY ENTRY TABLE FOR ON DUTY 
		$check_on_duty_query   = 'SELECT on_duty_date,on_duty_count from cw_on_duty_entry WHERE employee_code = "'. $employee_code .'" and on_duty_date between "'.$from_date.'" and "'.$to_date.'" and financial_setting_id = '.$prime_financial_id.' and on_duty_status not in (3,4) and trans_status = 1';
		$check_on_duty_info    = $this->runQuery("$check_on_duty_query");
		$check_on_duty_rlst    = $this->result_array($check_on_duty_info);
		$check_leave_rlst      = array_reduce($check_leave_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['leave_date']))] = $arr;
	    	return $result;
		}, array());
		$check_on_duty_rlst    = array_reduce($check_on_duty_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['on_duty_date']))] = $arr;
	    	return $result;
		}, array());

		$check_request_rlst   = "";
		$direct_leave_rlst    = "";
		$check_request_query  = 'SELECT from_date,to_date,from_date_type,to_date_type,request_type from cw_request WHERE employee_code = "'. $employee_code .'" and financial_setting_id = '.$prime_financial_id.' and leave_status not in (3,4) and trans_status = 1';
		$check_request_info   = $this->runQuery("$check_request_query");
		$check_request_rlst   =  $this->result_array($check_request_info);
		//CHECK A DIRECT LEAVE ENTRY TABLE FOR THIS SAME DATE ALREADY LEAVE APPLIED OR NOT
		$direct_leave_query  = 'SELECT from_date,to_date,from_date_type,to_date_type,request_type from cw_direct_leave_entry WHERE employee_code = "'. $employee_code .'" and financial_setting_id = '.$prime_financial_id.' and trans_status = 1';
		$direct_leave_info   = $this->runQuery("$direct_leave_query");
		$direct_leave_rlst   = $this->result_array($direct_leave_info);

		$request_from_rlst   = array_reduce($check_request_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['from_date']))][] = $arr['from_date_type'];
	    	return $result;
		}, array());

		$request_from_type   = array_reduce($check_request_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['from_date']))] = $arr['request_type'];
	    	return $result;
		}, array());

		$request_to_rlst     = array_reduce($check_request_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['to_date']))][] = $arr['to_date_type'];
	    	return $result;
		}, array());

		$request_to_type     = array_reduce($check_request_rlst ?? [], function($result, $arr){			
	    	$result[date("d-m-Y",strtotime($arr['to_date']))] = $arr['request_type'];
	    	return $result;
		}, array());		

		$direct_leave_from_rlst  = array_reduce($direct_leave_rlst ?? [], function($result, $arr){	
			$result[date("d-m-Y",strtotime($arr['from_date']))][] = $arr['from_date_type'];
			return $result;
		}, array());

		$direct_leave_from_type  = array_reduce($direct_leave_rlst ?? [], function($result, $arr){		
			$result[date("d-m-Y",strtotime($arr['from_date']))] = $arr['request_type'];
			return $result;
		}, array());

		$direct_leave_to_rlst    = array_reduce($direct_leave_rlst ?? [], function($result, $arr){	
			$result[date("d-m-Y",strtotime($arr['to_date']))][] = $arr['to_date_type'];
			return $result;
		}, array());

		$direct_leave_to_type    = array_reduce($direct_leave_rlst ?? [], function($result, $arr){	
			$result[date("d-m-Y",strtotime($arr['to_date']))] = $arr['request_type'];
			return $result;
		}, array());

		$request_from_rlst   = array_merge($request_from_rlst ?? [], $direct_leave_from_rlst ?? []);
		$request_from_type   = array_merge($request_from_type ?? [], $direct_leave_from_type ?? []);
		$request_to_rlst     = array_merge($request_to_rlst  ?? [], $direct_leave_to_rlst ?? []);
		$request_to_type     = array_merge($request_to_type  ?? [], $direct_leave_to_type ?? []);

		//SK AND DK LEAVE ALLOW VALIDATION
		$from_date_arr       = array();
		$to_date_arr         = array();
		$check_request_type  = "";

		if(array_key_exists($from_date,$request_from_rlst ?? []) || array_key_exists($to_date,$request_from_rlst ?? [])){
			if($request_from_rlst[$from_date]){
				$from_date_arr[$from_date] = $request_from_rlst[$from_date][0];
			}
			if($request_from_rlst[$to_date]){				
				$from_date_arr[$to_date]   = $request_from_rlst[$to_date][0];				
			}			
		}
		if(array_key_exists($from_date,$request_to_rlst ?? []) || array_key_exists($to_date,$request_to_rlst ?? [])){
			if($request_to_rlst[$from_date]){
				if($request_to_rlst[$from_date][0] && $request_to_rlst[$from_date][1]){
					$to_date_arr[$from_date]   = $request_to_rlst[$from_date][1];
				}else{
					$to_date_arr[$from_date]   = $request_to_rlst[$from_date][0];
				}
				
			}
			if($request_to_rlst[$to_date]){
				if($request_to_rlst[$to_date][0] && $request_to_rlst[$to_date][1]){
					$to_date_arr[$to_date]     = $request_to_rlst[$to_date][1];
				}else{
					$to_date_arr[$to_date]     = $request_to_rlst[$to_date][0];
				}				
			}
		}
		$check_exist         = 0;
		$from_leave_allow    = 0;
		$to_leave_allow      = 0;
		$message             = "";	
		if(array_key_exists($from_date,$from_date_arr ?? [])){
			if($from_date_arr[$from_date] === $from_date_type || $to_date_arr[$from_date] === $from_date_type || (int)$from_date_type === 1){
				$check_exist         = 1;	
				$check_request_type  = $request_from_type[$from_date];
				if($to_date_arr[$from_date] === $from_date_type){
					$check_request_type  = $request_to_type[$from_date];
				}		
			}else{
				if((int)$from_date_arr[$from_date] === 1){
					$check_exist = 1;
					$check_request_type  = $request_from_type[$from_date];	
				}else
				if((int)$from_date_arr[$from_date] === 2){
					$from_leave_allow = 3;
					$check_exist = 1;
				}else{
					$from_leave_allow = 2;
					$check_exist = 1;
				}						
			}	
			// $message = "You are Already Leave Applied in this From Date..";
		}else
		/* SATHISH - START */
		if(array_key_exists($from_date,$to_date_arr ?? [])){
			if($from_date_arr[$from_date] === $from_date_type || (int)$from_date_arr[$from_date] === 1 || (int)$from_date_type === 1){
				$check_exist = 1;		
				$check_request_type  = $request_from_type[$from_date];			
			}else{
				if((int)$to_date_arr[$from_date] === 1){
					$check_exist = 1;
					$check_request_type  = $request_to_type[$from_date];			
				}else
				if((int)$to_date_arr[$from_date] === 2){
					$from_leave_allow = 3;
					$check_exist = 1;
				}else{
					$from_leave_allow = 2;
					$check_exist = 1;
				}						
			}	
		}
		/* SATHISH - END */
		if(array_key_exists($to_date,$to_date_arr ?? [])){
			if($from_date_arr[$to_date] === $to_date_type || $to_date_arr[$to_date] === $to_date_type || (int)$to_date_type === 1){
				$check_exist = 2;
				if($from_date_arr[$to_date] === $to_date_type){
					$check_request_type  = $request_from_type[$to_date];
				}
				$check_request_type  = $request_to_type[$to_date];			
			}else{
				if((int)$to_date_arr[$to_date] === 1){
					$check_exist = 2;
					
					$check_request_type  = $request_to_type[$to_date];	
				}else
				if((int)$to_date_arr[$to_date] === 2){
					$to_leave_allow = 3;
					$check_exist = 2;
					
				}else{
					$to_leave_allow = 2;
					$check_exist = 2;
				}		
			}	
			// $message = "You are Already Leave Applied in this To Date..";
		}else
		if(array_key_exists($to_date,$from_date_arr ?? [])){
			/* SATHISH - START */
			if($from_date_arr[$to_date] === $to_date_type || (int)$from_date_arr[$to_date] === 1 || (int)$to_date_type === 1){
				$check_exist = 2;
				$check_request_type  = $request_from_type[$to_date];	
			}else{
				if((int)$to_date_arr[$to_date] === 1){
					$check_exist = 2;
					$check_request_type  = $request_to_type[$to_date];	
				}else
				if((int)$to_date_arr[$to_date] === 2){
					$to_leave_allow = 3;
					$check_exist = 2;
				}else{
					$to_leave_allow = 2;
					$check_exist = 2;
				}		
			}
		/* SATHISH - END */	
		/* DHINESH - START */
		}else // FOR LEAVE ENTRY TABLE ARRAY
		if(array_key_exists(date('d-m-Y',strtotime($from_date)),$check_leave_rlst ?? []) || array_key_exists($to_date,$check_leave_rlst ?? []))
		{
			$check_exist = 1;
			$message = "Already Leave Applied in this Date ..";
		}else// FOR ON DUTY ENTRY TABLE ARRAY
		if(array_key_exists(date('d-m-Y',strtotime($from_date)),$check_on_duty_rlst ?? []) || array_key_exists($to_date,$check_on_duty_rlst ?? [])){
			$check_exist = 1;
			$message = "Already OD Applied in this Date ..";
		}
		
		// FOR LEAVE ENTRY TABLE
		unset($check_leave_rlst[date('d-m-Y',strtotime($from_date))]);
		unset($check_leave_rlst[date('d-m-Y',strtotime($to_date))]);
		// FOR ON DUTY ENTRY TABLE
		unset($check_on_duty_rlst[date('d-m-Y',strtotime($from_date))]);
		unset($check_on_duty_rlst[date('d-m-Y',strtotime($to_date))]);
		/* DHINESH - END */
		if(count($check_leave_rlst ?? []) > 0){
			$check_exist = 3;
			$message = "You are Already Leave Applied in Between From Date or To Date..";
		}else
		if(count($check_on_duty_rlst ?? []) > 0){
			$check_exist = 3;
			$message = "You are Already On Duty Applied in Between From Date or To Date..";
		}else{
			if((int)$check_exist > 0){
				if((int)$check_exist === 1){
					if((int)$from_leave_allow > 1){
						if((int)$from_leave_allow === (int)$from_date_type){
							$check_exist = 0;
						}else{
							$message = "Can Allow From date type $from_leave_allow ..";
						}
					}else{
						if((int)$check_request_type === 1){
							
							$message = "Already Leave Applied in this Date";
						}else
						if((int)$check_request_type === 3){
							$message = "Already OD Applied in this Date";
						}
					}
				}
				if((int)$check_exist === 2){
					if((int)$to_leave_allow > 1){
						if((int)$to_leave_allow === (int)$to_date_type){
							$check_exist = 0;
						}else{
							$message = "Can Allow To date type $to_leave_allow ..";
						}
					}else{
						if((int)$check_request_type === 1){
							$message = "Already Leave Applied in this Date";
						}else
						if((int)$check_request_type === 3){
							$message = "Already OD Applied in this Date";
						}
					} 
				}
			}
		}
		/* BSK same day leave can only allow different leave type  END */
		if((int)$check_exist > 0){
			return $this->returnResult(FALSE,"OOps..!! $message",array("leave_count" => ""), []);
		}else{
			if((int)$request_type === 1 || (int)$request_type === 3){
				$fromToMonthValidation = $this->fromToMonthValidation($from_date,$to_date,"date");				
				if($fromToMonthValidation){
					return $this->returnResult(False, 'To Date Must Be Greater Than From Date', [], []);
				}
			}
			if((int)$request_type === 1){
				$leave_count = $this->total_no_of_days_count($employee_code,$request_type,$leave_type,$from_date,$to_date,$from_date_type,$to_date_type,$prime_financial_id,$leave_balance);
				$leave_count = number_format($leave_count,2);
				//for Get Leave Creation
				$leave_creation_qry    = 'SELECT leave_opening from cw_leave_creation where cw_leave_creation.trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
				$leave_creation_info   = $this->runQuery("$leave_creation_qry");
				$leave_creation_result = $this->result_array($leave_creation_info);
				$leave_opening         = $leave_creation_result[0]['leave_opening'];
				if((int)$leave_opening !== 1){ // FOR LOP
					return $this->returnResult(TRUE,'Success',array("leave_count" =>number_format($leave_count,2)), []);
				}else
                if((float)$leave_balance < (float)$leave_count){
                    return $this->returnResult(FALSE,'No of Leave Days Should Not Exceeded the Leave Balance...',array("leave_count" => $leave_count), []);
                }else{
                    return $this->returnResult(TRUE,'Success',array("leave_count" =>number_format($leave_count,2)), []);
                }
			}else{
                return $this->returnResult(TRUE,'Failed',array("leave_count" => ""), []);
			}	
		}
    }

    # TOTAL NO OF DAYS COUNT
    public function total_no_of_days_count($employee_code,$request_type,$leave_type,$from_date,$to_date,$from_date_type,$to_date_type,$prime_financial_id,$leave_balance){		
		$total_leave         = "";
		$from_date_diff      = strtotime($from_date);
		$to_date_diff        = strtotime($to_date);
		$datediff            = $to_date_diff - $from_date_diff;
		$no_of_days          = round($datediff / (60 * 60 * 24));
		$holiday_result      = array();
		$weekoff_result      = array();

		if((int)$request_type === 1 || (int)$request_type === 2 || (int)$request_type === 3 || (int)$request_type === 8){
			$startTimeStamp  = strtotime($from_date);
			$endTimeStamp    = strtotime($to_date);
			$timeDiff        = abs($endTimeStamp - $startTimeStamp);
			$numberDays      = $timeDiff/86400;  // 86400 seconds in one day
			// and you might want to convert to integer
			$numberDays      = intval($numberDays);
			$numberDays      = (int)$numberDays + 1;
			$date_range      = $this->getDatesFromRange($from_date, $to_date);
			$get_year        = date('Y',strtotime($from_date));

			//for Get Leave Creation
			$leave_creation_qry    = 'SELECT count(*) as creation_count,intervening_holidays,intervening_type,leave_name,coff from cw_leave_creation where cw_leave_creation.trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
			$leave_creation_info   = $this->runQuery("$leave_creation_qry");
			$leave_creation_result = $this->result_array($leave_creation_info);
			$intervening_holidays  = $leave_creation_result[0]['intervening_holidays'];
			$intervening_type      = explode(",",$leave_creation_result[0]['intervening_type'] ?? "");
			$leave_name  		   = $leave_creation_result[0]['leave_name'];
			$leave_name 		   = strtolower($leave_name);
			$creation_count 	   = $leave_creation_result[0]['creation_count'];
			$coff 	               = $leave_creation_result[0]['coff'];
			$pending_column 	   = "pending_".$leave_name;

			//SELECT QUERY FOR CHECK A GENENRAL SETTING PARAMETER BASED TYPE
			$param_based_type_qry  = 'SELECT parameter_type,based_on FROM cw_general_setting inner join cw_parameter_type on cw_parameter_type.prime_parameter_type_id = cw_general_setting.entry_parameter_type WHERE cw_general_setting.trans_status = 1';
			$param_based_type_info = $this->runQuery("$param_based_type_qry");
			$param_based_type_rslt = $this->result_array($param_based_type_info);

			$param_based_type_arr  = array_reduce($param_based_type_rslt ?? [], function($result, $arr){			
		    $result[$arr['parameter_type']] = $arr['based_on'];
		    return $result;
			}, array());
			$week_off_entry        = (int)$param_based_type_arr['Weekly off Entry'];	
			$holiday_entry         = (int)$param_based_type_arr['Holiday Entry'];	
			$leave_entry           = (int)$param_based_type_arr['Leave Entry'];	
			//CONDITION FOR CHECK A HOLIDAY DATE FOR PARAMETER TYPE BASED ON
			if($holiday_entry === 2){
				$holid_component_query  = 'SELECT label_name,components FROM cw_general_setting inner join cw_form_setting on cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 2 and cw_general_setting.trans_status = 1';
				$holid_component_info   = $this->runQuery("$holid_component_query");
				$holid_component_result = $this->result_array($holid_component_info);
			
				$holid_label_name    = $holid_component_result[0]['label_name'];
				//$holid_comp_value    = $this->emp_pick_arr[$employee_code][$holid_label_name];
				$emp_pick_arr        = $this->get_emp_data($employee_code);
				$holid_comp_value    = $emp_pick_arr[$employee_code][$holid_label_name];
				$holiday_qry  = 'select cw_holiday_entry_holiday_data.holiday_date from cw_holiday_entry inner join cw_holiday_entry_holiday_data on cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id where FIND_IN_SET("'.$holid_comp_value.'", cw_holiday_entry_holiday_data.component_value) and cw_holiday_entry.holiday_year = "'.$get_year.'" and cw_holiday_entry.trans_status = 1 and cw_holiday_entry_holiday_data.trans_status = 1';
				$holiday_info    = $this->runQuery("$holiday_qry");
				$holiday_result  = $this->result_array($holiday_info);
				$holiday_result  = array_reduce($holiday_result ?? [], function($result, $arr){			
				    $result[$arr['holiday_date']] = $arr;
				    return $result;
				}, array());
			}
			
			//CONDITION FOR CHECK A WEEKOFF DATE FOR PARAMETER TYPE BASED ON
			//echo $week_off_entry; die;
			if($week_off_entry === 1){
				$check_weekoff_qry   = 'SELECT employee_code,weekoff_date,weekoff_type from cw_weekoff_import WHERE employee_code = "'. $employee_code .'" and weekoff_date >= "'.$from_date.'" and weekoff_date <= "'.$to_date.'" and financial_setting_id = '.$prime_financial_id.' and trans_status = 1';
				$check_weekoff_info   = $this->runQuery("$check_weekoff_qry");
				$check_weekoff_rlst   = $this->result_array($check_weekoff_info);

				$weekoff_result       = array_reduce($check_weekoff_rlst ?? [], function($result, $arr){			
				    $result[$arr['employee_code']][$arr['weekoff_date']] = $arr['weekoff_type'];
				    return $result;
					}, array());
			}else
			if($week_off_entry === 2){
				//QUERY AND CODE ARE USED FOR GET A WEEK OFF AND HOLIDAY DETAILS
				$week_component_query  = 'SELECT label_name,components FROM cw_general_setting inner join cw_form_setting on cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 1 and cw_general_setting.trans_status = 1';
				$week_component_info   = $this->runQuery("$week_component_query");
				$week_component_result = $this->result_array($week_component_info);

				$week_label_name       = $week_component_result[0]->label_name;
				//$week_comp_value       = $this->emp_pick_arr[$employee_code][$week_label_name];
				$emp_pick_arr          = $this->get_emp_data($employee_code);
				$week_comp_value       = $emp_pick_arr[$employee_code][$week_label_name];
				/* Weekoff - START */
				$weekoff_qry = 'select cw_weekoff_entry_weekoff_days_details.weekday,cw_weekoff_entry_weekoff_days_details.first_week,cw_weekoff_entry_weekoff_days_details.second_week,cw_weekoff_entry_weekoff_days_details.third_week,cw_weekoff_entry_weekoff_days_details.fourth_week,cw_weekoff_entry_weekoff_days_details.fifth_week from cw_weekoff_entry inner join cw_weekoff_entry_weekoff_days_details on cw_weekoff_entry_weekoff_days_details.prime_weekoff_entry_id = cw_weekoff_entry.prime_weekoff_entry_id where FIND_IN_SET("'.$week_comp_value.'", cw_weekoff_entry.component_value) and cw_weekoff_entry.from_date <= "'.$from_date.'" AND cw_weekoff_entry.to_date >= "'.$to_date.'" and cw_weekoff_entry.trans_status = 1 and cw_weekoff_entry_weekoff_days_details.trans_status = 1';
				$weekoff_info   = $this->runQuery("$weekoff_qry");
				$weekoff_result = $this->result_array($weekoff_info);
				$weekoff_result = array_reduce($weekoff_result ?? [], function($result, $arr){		
				    $result[$arr['weekday']] = $arr;
				    return $result;
				}, array());
				
				/* Weekoff - END */
				$days_arr = array("sun"=>1,"mon"=>2,"tue"=>3,"wed"=>4,"thu"=>5,"fri"=>6,"sat"=>7);
				$week_arr = array(1=>"first_week",2=>"second_week",3=>"third_week",4=>"fourth_week",5=>"fifth_week");
			}

			$from_date_count  = 0;
			$to_date_count    = 0;
			if(!$leave_balance){
				$leave_balance =10;
			}

			//intervening holidays check for before from date
			if((int)$intervening_holidays === 1 && in_array("1",$intervening_type)){
				//echo "BSK";
				for($j=1;$j<=(int)$leave_balance;$j++){
					$date          = new DateTime($from_date);
					$date->modify("-$j day");
					$check_prev    = $date->format("Y-m-d");
					//WEEKOFF DATE CHECK					
					if($week_off_entry === 1){
						$weekoff_value = (int)$weekoff_result[$employee_code][$check_prev];		
					}else
					if($week_off_entry === 2){
						$get_day       = strtolower(date('D',strtotime($check_prev)));
						$day           = $days_arr[$get_day];
						$week_no       = $this->weekOfMonth(strtotime($check_prev)); 
						$week          = $week_arr[$week_no];
						$weekoff_value = $weekoff_result[$day][$week];	
					}
					//HOLIDAY DATE CHECK
					if($holiday_entry === 2){
						$prev_holiday  = $holiday_result[$check_prev]['holiday_date'];
					}	
					if($prev_holiday ||  $weekoff_value){
						$from_date_count = $from_date_count + 1;					
					}else{
						break;
					}									
				}
			}
			//intervening holidays check for after to date
			if((int)$intervening_holidays === 1 && in_array("2",$intervening_type)){
				//Check after todate
				for($i=1;$i<=(int)$leave_balance;$i++){			
					$after_date = new DateTime($to_date);
					$after_date->modify("$i day");
					$check_after = $after_date->format("Y-m-d");

					//WEEKOFF DATE CHECK
					if($week_off_entry === 1){
						$after_weekoff_value = (int)$weekoff_result[$employee_code][$check_after];		
					}else
					if($week_off_entry === 2){
						$get_after_day       = strtolower(date('D',strtotime($check_after)));
						$after_day           = $days_arr[$get_after_day];
						$after_week_no       = $this->weekOfMonth(strtotime($check_after)); 
						$after_week          = $week_arr[$after_week_no];
						$after_weekoff_value = $weekoff_result[$after_day][$after_week];		
					}
					//HOLIDAY DATE CHECK
					if($holiday_entry === 2){
						$after_holiday  = $holiday_result[$check_after]['holiday_date'];
					}	
					if($after_holiday || $after_weekoff_value){
						$to_date_count = $to_date_count + 1;
					}else{
						break;
					}	
				}	
			}	
			
			$end_key       = end(array_keys($date_range ?? []));
			$leave_count   = 0;
			$total_leave   = 0;
			foreach ($date_range as $key => $common_date){
				//WEEKOFF DATE CHECK
				if($week_off_entry === 1){
					$weekoff_value      = (int)$weekoff_result[$employee_code][$common_date];		
				}else
				if($week_off_entry === 2){
					$get_day            = strtolower(date('D',strtotime($common_date)));
					//Check weekoff day exist
					$day                = $days_arr[$get_day];
					$week_no            = $this->weekOfMonth(strtotime($common_date)); 
					$week               = $week_arr[$week_no];
					$weekoff_value      = $weekoff_result[$day][$week];		
				}
				//HOLIDAY DATE CHECK
				if($holiday_entry === 2){
					$get_common_holiday = $holiday_result[$common_date]['holiday_date'];
				}	
				
				if($key === 0){
					if((int)$from_date_type === 1){
						$leave_count = 1.00;
					}else
					if((int)$from_date_type === 2 || (int)$from_date_type === 3){
						$leave_count = 0.50;
					}
				}else
				if($key === $end_key){
					if((int)$to_date_type === 1){
						$leave_count = 1.00;
					}else
					if((int)$to_date_type === 2 || (int)$to_date_type === 3){
						$leave_count = 0.50;
					}
				}else{
					if((int)$weekoff_value === 1 || $get_common_holiday){
						if((int)$intervening_holidays === 1 && in_array("3",$intervening_type)){
							$leave_count = 1.00;
						}else{
							$leave_count = 0;
						}						
					}else
					if((int)$weekoff_value === 2 && ((int)$intervening_holidays === 1 && in_array("3",$intervening_type))){
						$leave_count = 0.50;
					}else
					if((int)$weekoff_value === 3 && ((int)$intervening_holidays === 1 && in_array("3",$intervening_type))){
						$leave_count = 0.50;
					}else{
						$leave_count = 1.00;
					}
				}
				$total_leave = $total_leave + $leave_count;
			}
			$total_leave = $total_leave + $from_date_count + $to_date_count;
			return $total_leave;
		}
	}

    # TIME OFFICE SETTING BASED MONTH DAY QRY FUNCTION 
	public function tos_day_qry_fun($entry_parameter){
		$tos_mon_day_qry   = 'select day_conditions,day_count,day_start,day_end FROM cw_tos_month_day INNER JOIN cw_tos_parameter ON cw_tos_parameter.prime_tos_parameter_id = cw_tos_month_day.entry_parameter where cw_tos_parameter.trans_status = 1 and cw_tos_month_day.trans_status = 1 and cw_tos_month_day.entry_parameter = "'.$entry_parameter.'"';
		$tos_mon_day_info  = $this->runQuery("$tos_mon_day_qry");
		$tos_mon_day_rslt  = $this->result($tos_mon_day_info);
		return $tos_mon_day_rslt;
	}

    public function getDatesFromRange($start,$end,$format = 'Y-m-d') {
	    $array 			= array();
	    $array_error 	= array();
	    $date_build_arr = "";
	    $interval 		= new DateInterval('P1D');
	    $realEnd 		= new DateTime($end);
	    $realEnd->add($interval);
	    $period 		= new DatePeriod(new DateTime($start), $interval, $realEnd);
	    foreach($period as $date) { 
	    	$check_date 	= $date->format($format);
	    	$date_build_arr = $date_build_arr[$r_key];
	    	if(in_array($check_date, $array)){
	    		$array_error[] = $date->format($format);
	    	}else{
	    		$array[] = $date->format($format);
	    	}
	    }
	    return $array;
    }
	
    public function get_emp_data($employee_code){
		//QUERY FOR GET A EMPLOYEE PICKLIST LABEL NAMES FROM FORM SETTING TABLE
		$get_components        = 'select GROUP_CONCAT(label_name) as label_name from `cw_form_setting` where prime_module_id = "employees" and input_view_type in (1,2) and field_type in (4,5) ORDER BY label_name';
		$get_components_info   = $this->runQuery("$get_components");
		$get_components_result = $this->result_array($get_components_info);
		$label_names           = $get_components_result[0]['label_name'];	
		// if((int)$this->logged_user_role === 1 || (int)$this->logged_user_role === 2){
		// 	$qry = "";
		// }else{
			$qry = 'employee_code = "'. $employee_code .'" and';
		// }
		$emp_pick_query  = 'SELECT role as category,'.$label_names.',employee_code from cw_employees WHERE '.$qry.'  trans_status = 1';
		$emp_pick_info   = $this->runQuery("$emp_pick_query");
		$emp_pick_rlst   = $this->result_array($emp_pick_info);

		$emp_pick_arr    = array_reduce($emp_pick_rlst ?? [], function($result, $arr){			
	    	$result[$arr['employee_code']] = $arr;
	    	return $result;
		}, array());
		return $emp_pick_arr;
	}

    # LEAVE BALANCE [MS 21-11-2024]
    public function leaveBalance($json){
        $employee_code   = $json->code;
        $leave_bal_arr   = $this->view_leave_details($employee_code,"leaveBalance");
        return $this->returnResult(TRUE,'Success',$leave_bal_arr, []);
    }

    # MY LEAVES [MS 21-11-2024]
    public function myLeaves($json){
        $employee_code       = $json->code;
        $leaveType           = $json->leaveType;
        $financial_info      = $this->get_leave_financial_details();
		$prime_financial_id  = $financial_info[0]->prime_leave_financial_year_id;
        $leave_qry           = 'SELECT cw_leave_status.leave_status,leave_date,DATE_FORMAT(leave_date, "%d %b %Y") AS formatted_date,DATE_FORMAT(leave_date, "%W") AS formatted_day,CASE WHEN leave_count = 0.50 THEN "Half Day" WHEN leave_count = 1.00 THEN "Full Day" ELSE "Invalid Status" END AS day_status FROM cw_leave_entry INNER JOIN cw_leave_status ON cw_leave_status.prime_leave_status_id = cw_leave_entry.leave_status WHERE employee_code = "'.$employee_code.'" AND leave_type = "'.$leaveType.'" AND cw_leave_entry.leave_status = 2 AND financial_setting_id = "'.$prime_financial_id.'" and cw_leave_entry.trans_status = 1 ';
        $my_leave_info       = $this->runQuery("$leave_qry");
		$my_leave_rslt       = $this->result_array($my_leave_info);
        $leave_rslt          = [];
        foreach($my_leave_rslt as $val){
            $leave_rslt[$val['leave_date']] = $val;
        }
        if(count($leave_rslt ?? []) <= 0){
            $leave_rslt       = ['msg' => 'No Data Available..'];
        }
        return $this->returnResult(TRUE,'Success',$leave_rslt, []);
    }

    # CALENDAR POPUP [MS 21-11-2024]    
    public function popupCalendar($json){
        $employee_code       = $json->code;
        $date                = $json->date;
		$req_exist_qry       = 'SELECT COUNT(*) as count FROM cw_request WHERE employee_code = "'.$employee_code.'" AND CASE WHEN request_type IN (1,3,8) THEN from_date <= "'.$date.'" AND to_date >= "'.$date.'" WHEN request_type NOT IN (1,3,4,8) THEN shift_date = "'.$date.'" WHEN request_type = 4 THEN permission_date = "'.$date.'" END AND trans_status = 1 and leave_status in (1,2)';
		$req_exist_info      = $this->runQuery("$req_exist_qry");
		$req_exist_rslt      = $this->result_array($req_exist_info);
		$req_exist_count     = $req_exist_rslt[0]['count'];

        $popup_qry           = 'SELECT employee_code,att_date,DATE_FORMAT(cw_time_entry.punch_in, "%H:%i") AS punch_in,DATE_FORMAT(cw_time_entry.punch_out, "%H:%i") AS punch_out,IF(cw_time_entry.early_in > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.early_in/60),":",LPAD(MOD(cw_time_entry.early_in,60),2,"0")),"%H:%i"), cw_time_entry.early_in) AS early_in,IF(cw_time_entry.excess_out > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.excess_out/60),":",LPAD(MOD(cw_time_entry.excess_out,60),2,"0")),"%H:%i"), cw_time_entry.excess_out) AS excess_out,IF(cw_time_entry.total_excess_hours > 0, TIME_FORMAT(CONCAT(FLOOR(cw_time_entry.total_excess_hours/60),":",LPAD(MOD(cw_time_entry.total_excess_hours,60),2,"0")),"%H:%i"), cw_time_entry.total_excess_hours) AS eligible_ot,whole_day_status,cw_shift_master.shift_name,cw_shift_master.from_time,cw_shift_master.to_time,first_half_status,first_half_count,second_half_status,second_half_count,permission_in,permission_out,final_total_work_hours,total_permission FROM cw_time_entry INNER JOIN cw_shift_master ON cw_shift_master.prime_shift_master_id = cw_time_entry.shift_id  WHERE employee_code = "'.$employee_code.'" AND att_date = "'.$date.'" AND cw_time_entry.trans_status = 1';
        $popup_info          = $this->runQuery("$popup_qry");
		$popup_rslt          = $this->result_array($popup_info);
		
        if(count($popup_rslt ?? []) > 0){
			$whole_day_sts                      = $popup_rslt[0]['whole_day_status'];
			$popup_rslt[0]['request_exist']     = '2';
			$popup_rslt[0]['allow_request']     = '2';
			$unpunch_invalid_arr                = array("U","UL","LU","UO","OU","UM","MU","UP","PU","FP","SP","IU","UI","FL","SL","I","IL","LI","IO","OI","IM","MI","IU","UI","IP","PI");
			// ALLOW TO APPLY REQUEST IN MOBILE 
			if(in_array($whole_day_sts,$unpunch_invalid_arr)){
				$popup_rslt[0]['allow_request'] = '1';
			}	
			// REQUEST ALREADY EXIST
			if($req_exist_count > 0){
				$popup_rslt[0]['request_exist'] = '1';
			}
            return $this->returnResult(TRUE,'Success',$popup_rslt, []);
        }else{
            return $this->returnResult(FALSE,'No Data Available',[], []);
        }
    } 

    # HISTORY API [MS 21-11-2024]    
    public function history($json){
        $employee_code       = $json->code;
        $financial_info      = $this->get_leave_financial_details();
        $starting_date       = $financial_info[0]->starting_date;
        $ending_date         = $financial_info[0]->ending_date;
        $get_events          = $this->get_events($employee_code,$starting_date,$ending_date,"history");
        return $this->returnResult(TRUE,'Success',$get_events, []);
    }

    # TIME DIFF CALCULATION [MS 22-11-2024]    
    public function timeDiffCalculate($json){
		$in_time          = $json->in_time;
		$out_time         = $json->out_time;
		//CONVERT STRING TO DATE FORMAT
		if (strtotime($in_time) && strtotime($out_time)) { // Ensure valid time strings
			if (strtotime($in_time) >= strtotime($out_time)) {
				return $this->returnResult(FALSE,'Out Time Must Be Greater Than In Time..',array('total_time' => ''), []);				
			}
		}else{
			return $this->returnResult(FALSE,'Invalid time format provided..',array('total_time' => ''), []);
		}
		$in_time          = new DateTime($in_time);
   		$out_time         = new DateTime($out_time);
   		$timeDiff         = $in_time->diff($out_time);
   		$total_time       = $timeDiff->format("%H:%I:%S");
		if($total_time){
            return $this->returnResult(TRUE,'Success',array('total_time' => $total_time), []);
		}else{
            return $this->returnResult(FALSE,'Please Check Your In Time and Out Time',array('total_time' => ''), []);
		}
	}

    # FUNCTION FOR MANUAL PUNCH [MS 22-11-2024]  
	public function diffDateTimeCal($json){
		$in_date         = date("Y-m-d",strtotime($json->in_date));
		$out_date        = date("Y-m-d",strtotime($json->out_date));
		$in_time         = $json->in_time;
		$out_time        = $json->out_time; 
		$in_time_count   = count(explode(":",$in_time ?? "") ?? []);
		$out_time_count  = count(explode(":",$out_time ?? "") ?? []);  
		$total_time      = $this->total_time_cal($in_date,$out_date,$in_time,$out_time,$in_time_count,$out_time_count);
		if($total_time){
            return $this->returnResult(TRUE,'Success',array('total_time' => $total_time), []);
		}else{ 
			return $this->returnResult(FALSE,'Please Check Your In Time and Out Time---',array('total_time' => ''), []);
		}
	}

    public function total_time_cal($in_date,$out_date,$in_time,$out_time,$in_time_count,$out_time_count){
		$total_time          = "";
		$days                = "";
		if((int)$in_time_count === 2){
			$in_time         = $in_time.":00";
		}
		if((int)$out_time_count === 2){
			$out_time        = $out_time.":00";
		}
		//CONVERT STRING TO DATE FORMAT
		if($in_date === $out_date){
			if(strtotime("$in_date $in_time") < strtotime("$out_date $out_time")){ // [MS 10-12-2024]
				$in_time     = new DateTime($in_time);
		   		$out_time    = new DateTime($out_time);
		   		$timeDiff    = $in_time->diff($out_time);
		   		$days        = (int)$timeDiff->days;
		   		$total_time  = $timeDiff->format("%H:%I:%S");
			}else{
				$total_time  = "";
			}	
		}else{
			if(strtotime("$in_date $in_time") < strtotime("$out_date $out_time")){
				$in_date      = new DateTime($in_date." ".$in_time);
				$out_date     = new DateTime($out_date." ".$out_time);			
				$timeDiff     = $in_date->diff($out_date);
				$days         = (int)$timeDiff->days;
				$totalHours   = ($timeDiff->days * 24) + $timeDiff->h;
				$totalMinutes = $timeDiff->i;
				$totalSeconds = $timeDiff->s;			
				$total_time   = sprintf('%02d:%02d:%02d', $totalHours, $totalMinutes, $totalSeconds);
			}else{
				$total_time   = "";
			}
		}
		if($total_time && ($days === 0 || $days === 1)){
			return $total_time;
		}else{
			return false;
		}
	}

    # LEAVE MANAGEMENT [MS 22-11-2024]  
    public function leaveManagement($json){		
		$validate_jwt          = $this->validate_jwt();
		$user_right            = $validate_jwt->user_right;
        $employee_code         = $json->code;
        $leave_status          = $json->leaveStatus;
        $module                = $json->module;
		$filter                = $json->filter;
        $financial_info        = $this->get_leave_financial_details();
		$prime_financial_id    = $financial_info[0]->prime_leave_financial_year_id;
        $role_condition        = $this->role_based_fun($employee_code,$module,$user_right);
        $prime_table           = 'cw_'.$module;
		
		// BASED ON FILTER KEY VALUES THEY QUERY AS WORK BY -AR
		$filter_condition      = '';
		foreach($filter[0] as $key => $value){
			$filter_condition .= ' AND ' . $prime_table . '.' . $key . ' = "' . $value . '"';
		}
		// END -AR
		// THIS IS CHECKING MODULE VALUE TO DECISIDES THE FUNCTIONALITY
		if($module === "approval"){
			$req_date          = "applied_on";
			$order_col         = 'prime_approval_id';
			
		}else
		if($module === "request"){
			$req_date          = "request_date";
			$order_col         = 'prime_request_id';
			$emp_qry           = ''.$prime_table.'.employee_code = "'.$employee_code.'" AND';
		}else{
			return $this->returnResult(FALSE,'Invalid Module..',[], []);
		}		

		if((int)$leave_status === 5){
			$leave_sts_qry     = " AND leave_status = 1 ";
		}else{
			$leave_sts_qry     = ' AND '.$prime_table.'.leave_status IN ("'.$leave_status.'")';
		}
		//GET BASEURL 
		$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
		$baseurl  = $protocol."://".$_SERVER['SERVER_NAME'].dirname($_SERVER["REQUEST_URI"].'?');
        $baseurl  = str_replace('api','',$baseurl);		
        $leaveManagement_qry   = 'SELECT '.$prime_table.'.prime_'.$module.'_id,'.$prime_table.'.employee_code,cw_employees.emp_name,'.$req_date.' as request_date,'.$prime_table.'.request_type,cw_request_type.request_type as req_desc,b.shift_name AS current_shift,first_approval_leave_status,second_approval_leave_status,first_approval_cancel_status,second_approval_cancel_status,cancellation_request,leave_status,'.$prime_table.'.first_level_approval,CONCAT(first_level_table.employee_code," ~ ",first_level_table.emp_name) AS first_level_name,'.$prime_table.'.second_level_approval,CONCAT(second_level_table.employee_code," ~ ",second_level_table.emp_name) AS second_level_name,IF(cancellation_request = 1,cancellation_reason,reason) as reason,from_date,from_date_type,to_date,to_date_type,no_of_days,shift_date,CONCAT(UCASE(LEFT(cw_leave_creation.leave_description, 1)),SUBSTRING(cw_leave_creation.leave_description, 2)) as leave_description,rejected_reason,contact_no,a.shift_name AS change_shift,'.$prime_table.'.in_date,'.$prime_table.'.out_date,'.$prime_table.'.permission_date,'.$prime_table.'.in_time,'.$prime_table.'.out_time,'.$prime_table.'.total_time,CASE WHEN '.$prime_table.'.request_type in ("1","3","8") THEN CONCAT(DATE_FORMAT('.$prime_table.'.from_date,"%d-%m-%Y")," - ",DATE_FORMAT('.$prime_table.'.to_date,"%d-%m-%Y")) WHEN  '.$prime_table.'.request_type = "3" THEN CONCAT(DATE_FORMAT('.$prime_table.'.from_date,"%d-%m-%Y")," - ",DATE_FORMAT('.$prime_table.'.to_date,"%d-%m-%Y")) ELSE DATE_FORMAT(shift_date,"%d-%m-%Y") END AS requested_date,cw_shift_master.shift_name,IF(business_file <> "",CONCAT("'.$baseurl.'",business_file),business_file) as business_file FROM '.$prime_table.' LEFT JOIN cw_employees on '.$prime_table.'.employee_code = cw_employees.employee_code LEFT JOIN cw_employees AS first_level_table ON  first_level_table.employee_code = '.$prime_table.'.first_level_approval LEFT JOIN cw_employees AS second_level_table ON  second_level_table.employee_code = '.$prime_table.'.second_level_approval LEFT JOIN cw_shift_master ON cw_shift_master.prime_shift_master_id = '.$prime_table.'.shift_name LEFT JOIN cw_leave_creation ON cw_leave_creation.prime_leave_creation_id = '.$prime_table.'.leave_type LEFT JOIN cw_request_type ON cw_request_type.prime_request_type_id = '.$prime_table.'.request_type LEFT JOIN cw_shift_master a ON a.prime_shift_master_id = '.$prime_table.'.change_shift  LEFT JOIN cw_shift_master b ON b.prime_shift_master_id= '.$prime_table.'.current_shift  WHERE '.$emp_qry. '  '.$prime_table.'.trans_status = 1 AND '.$prime_table.'.financial_setting_id = "'.$prime_financial_id.'" '.$role_condition.' '.$leave_sts_qry.' '.$filter_condition.' ORDER BY '.$order_col .' DESC';		
        $leaveManagement_info  = $this->runQuery("$leaveManagement_qry");
		$leaveManagement_rslt  = $this->result($leaveManagement_info);
        if($leaveManagement_info){
			if(count($leaveManagement_rslt ?? []) > 0){
				return $this->returnResult(TRUE,'Success',array("leave_result" => $leaveManagement_rslt), []);
			}else{
				return $this->returnResult(TRUE,'No data Avaliable..',[], []);
			}
		}else{
            return $this->returnResult(FALSE,'Please Try After Some Time..',[], []);
		}
    }

    # EMP Info
    public function empInfo($json){
		$this->validate_jwt(); # JWT TOKEN
		$code          = $json->code ?? null;
		if(!$code){
			return $this->returnResult(False, 'Failed - Employee code required', [], []);
		}
		$emp_qry       = 'SELECT date_of_joining,mobile_number,company_email_id,permanent_address,aadhar_card_no,pan_number,cw_blood_group.blood_group,cw_marital_status.marital_status,emp_name,device_code,cw_department.department,cw_position.position_name AS designation,cw_location.location,cw_branch.branch,date_of_birth,cw_gender.gender,cw_bank_name.bank_name,bank_account_number,bank_branch,ifsc_code,cw_status_mode.status_mode_value AS metro,esi_number,cw_income_tax_type.income_tax_type,cw_professional_tax_location.professional_tax_location,uan_number,pf_account_number,role as category,mobile_checkin,checkin_mode,loc_allow FROM cw_employees LEFT JOIN cw_blood_group ON cw_blood_group.prime_blood_group_id = cw_employees.blood_group LEFT JOIN cw_marital_status ON cw_marital_status.prime_marital_status_id = cw_employees.marital_status LEFT JOIN cw_department ON cw_department.prime_department_id = cw_employees.department LEFT JOIN cw_position ON cw_position.prime_position_id = cw_employees.designation LEFT JOIN cw_location ON cw_location.prime_location_id = cw_employees.location LEFT JOIN cw_branch ON cw_branch.prime_branch_id = cw_employees.branch LEFT JOIN cw_gender ON cw_gender.prime_gender_id = cw_employees.gender LEFT JOIN cw_bank_name ON cw_bank_name.prime_bank_name_id = cw_employees.bank_name LEFT JOIN cw_status_mode ON cw_status_mode.prime_status_mode_id = cw_employees.metro LEFT JOIN cw_professional_tax_location ON cw_professional_tax_location.prime_professional_tax_location_id = cw_employees.professional_tax_location LEFT JOIN cw_income_tax_type on cw_income_tax_type.prime_income_tax_type_id = cw_employees.income_tax_type WHERE cw_employees.trans_status = 1 AND employee_code = "'.$code.'"';
		$emp_info      = $this->runQuery($emp_qry);
		$emp_rslt      = $this->result($emp_info);
		$current_date  = date_create(date('Y-m-d'));
		$doj           = date_create($emp_rslt[0]->date_of_joining);
		$total_years   = date_diff($doj,$current_date);
		$total_years   = $total_years->format('%R%y years %m months');
		$emp_rslt[0]->total_years = $total_years; // TOTAL YEASRS OF EXPERIENCE

		if($emp_rslt[0]->loc_allow){
			$loc_qry  = 'SELECT loc_latitude,loc_longitude,radius,location FROM cw_location WHERE trans_status = 1 AND prime_location_id in ('.$emp_rslt[0]->loc_allow.')';
			$loc_info = $this->runQuery($loc_qry);
			$loc_rslt = $this->result($loc_info);
		}		
		if($emp_rslt){
			return $this->returnResult(True,'Success - In and Out time',['emp_rslt' => $emp_rslt,'allowed_locations' => $loc_rslt ?? []], []);
		}else{
			return $this->returnResult(True,'Failed - No data found',[], []);
		}
	}

    # PERMISSION REQUEST
    public function permissionRequest($json){	
		$this->validate_jwt(); # JWT TOKEN	
        $employee_code       = $json->code;
        $permission_date     = $json->permission_date;
        $shift_name          = $json->shift_name;
        $in_time             = $json->in_time;
        $out_time            = $json->out_time;
        $total_time          = $json->total_time;
        $permission_type     = $json->permission_type;       
		$financial_info      = $this->get_leave_financial_details();
		$financial_year_id   = $financial_info[0]->prime_leave_financial_year_id;
		//TIME CONVERT TO MINUTES 
		$total_time_arr      = explode(':', $total_time ?? "");
    	$total_time          = round(($total_time_arr[0]*60) + ($total_time_arr[1]));
		
    	$per_setting_check   = $this->permission_setting_check($employee_code,$permission_date,$shift_name,$in_time,$out_time,$total_time,$permission_type);
		if($per_setting_check){
			return $this->returnResult(True,'Ok - Proceed..!',[], []);
		}
    }

    public function permission_setting_check($employee_code,$permission_date,$shift_name,$in_time,$out_time,$total_time,$permission_type){
		$component_value_arr    = $this->general_setting_info(3);
		$component_value        = $component_value_arr[0]->based_on;
		//COMPONENT AND SHIFT NAME BASED SELECT A PERMISSION SETTINGS DATA
		$permission_setting_qry      = 'SELECT allowed_per_month,allowed_per_day,no_of_permissions,permission_allow FROM cw_permission_setting WHERE FIND_IN_SET("'.$component_value.'", cw_permission_setting.component_value) and FIND_IN_SET("'.$shift_name.'", cw_permission_setting.shift_name) and trans_status = 1';
		$permission_setting_info     = $this->runQuery("$permission_setting_qry");
		$permission_setting_result   = $this->result_array($permission_setting_info);
		$allow_per_month     = $permission_setting_result[0]['allowed_per_month'];
		$allow_per_month_arr = explode(':', $allow_per_month ?? "");
    	$allow_per_month     = round(($allow_per_month_arr[0]*60) + ($allow_per_month_arr[1]));

		$allow_per_day       = $permission_setting_result[0]['allowed_per_day'];
		$allow_per_day_arr   = explode(':', $allow_per_day ?? "");
    	$allow_per_day       = round(($allow_per_day_arr[0]*60) + ($allow_per_day_arr[1]));

		$no_of_permissions   = $permission_setting_result[0]['no_of_permissions'];

		$permission_allow    = (int)$permission_setting_result[0]['permission_allow'];
		$salary_start_date   = "";
		$salary_end_date     = "";
		if($allow_per_month && $no_of_permissions && $allow_per_day){
			if(($allow_per_month < $total_time) && (int)$permission_type === 1){		
                echo $this->returnResult(FALSE,'You Have Reached Maximum Hours per Month..?',[], []);	
				exit(0);	
			}else
			if(($allow_per_day < $total_time) && (int)$permission_type === 1){
                echo $this->returnResult(FALSE,'You Have Reached Maximum Hours per Day?',[], []);
				exit(0);
			}else{
				//GTE DEFAULT FINANCIAL YEAR
				$financial_info        = $this->get_leave_financial_details();
				$prime_financial_id    = $financial_info[0]->prime_leave_financial_year_id;	
				$starting_date         = date('Y-m-d',strtotime($financial_info[0]->starting_date));	
				$ending_date           = date('Y-m-d',strtotime($financial_info[0]->ending_date));	
				$month_day_info        = $this->tos_day_info($employee_code,"4"); // dont change this
				if(count($month_day_info ?? [])){
					$salary_start_date =  date("Y-m-d",strtotime($month_day_info['salary_start_date']));
					$salary_end_date   = date("Y-m-d",strtotime($month_day_info['salary_end_date']));
					$year_end_date     = date("Y-m-d",strtotime($month_day_info['year_end_date']));
					$check_sts         = false;
					// if($permission_date > $salary_end_date || $permission_date < $salary_start_date){
					// 	echo $this->returnResult(FALSE,'Permission will allow only for Current Salary..',[], []);
					// 	exit(0);
					// }
					if($permission_date >= $salary_start_date && $permission_date <= $year_end_date){
						$check_sts     = true;
					}
					if($check_sts){
						$permission_entry_qry      = 'SELECT count(cw_permission_entry.prime_permission_entry_id) as count,SUM(total_minute) as total_time,employee_code,permission_date,shift_name FROM cw_permission_entry WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.permission_date >= "'.$salary_start_date.'" and cw_permission_entry.permission_date <= "'.$salary_end_date.'" and cw_permission_entry.leave_status in (1,2) and financial_setting_id = "'.$prime_financial_id.'" and trans_status = 1 and permission_type = "'.$permission_type.'" GROUP BY employee_code';
						$permission_entry_info     = $this->runQuery("$permission_entry_qry");
                        $permission_entry_result   = $this->result_array($permission_entry_info);
						$permission_entry_count    = $permission_entry_result[0]['count'];
						$month_permission_time     = $permission_entry_result[0]['total_time'];
						
						if(((int)$permission_entry_count >= (int)$no_of_permissions) && (int)$permission_type === 1){
                            echo $this->returnResult(FALSE,'Already You Have Reached Number of Permission Limit per month?',[], []);
							exit(0);
						}else{
							if($month_permission_time){
								$month_permission_time    = $month_permission_time + $total_time;
							}		
							if(($month_permission_time > $allow_per_month) && (int)$permission_type === 1){
                                echo $this->returnResult(FALSE,'Already You Have Reached Maximum Hours per Month?',[], []);
								exit(0);
							}else{
								$day_permission_time       = "";
								$permission_allow_day_qry  = 'SELECT count(cw_permission_entry.prime_permission_entry_id) as count,SUM(total_minute) as total_time FROM cw_permission_entry WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.permission_date = "'.$permission_date.'" and financial_setting_id = "'.$prime_financial_id.'" and cw_permission_entry.leave_status in (1,2) and trans_status = 1 GROUP BY employee_code';
								
								// and permission_type = "'.$permission_type.'"
								$permission_allow_day_info     = $this->runQuery("$permission_allow_day_qry");
                                $permission_allow_day_result   = $this->result_array($permission_allow_day_info);

								$exist_count                   = (int)$permission_allow_day_result[0]->count;	
								$day_permission_time           = $permission_allow_day_result[0]->total_time;
								if($day_permission_time){
									$day_permission_time       = $day_permission_time + $total_time;
								}
								if(($day_permission_time >= $allow_per_day) && (int)$permission_type === 1){
                                    echo $this->returnResult(FALSE,"Already You Have Reached Maximum Hours per Day?",[], []);
									exit(0);
								}else{
									//CHECK PERMISSION IN AND OUT TIME BASED ON PERMISSION SETTING (PERMISSION ALLOW ANYTIME INPUT)
									//FUNCTION FOR GET A SHIFT IN AND OUT TIME DR CODE
									$shift_master_rslt  = $this->shift_time_qry($shift_name);
									// echo "<pre>";
									// print_r($shift_master_rslt);die;
									$shift_id           = $shift_master_rslt[0]->prime_shift_master_id;
									$from_time          = date("H:i",strtotime($shift_master_rslt[0]['from_time']));
									$to_time            = date("H:i",strtotime($shift_master_rslt[0]['to_time']));	
									if(!$from_time || !$to_time){
                                        echo $this->returnResult(false,'Shift Time not Added to Shift Master.!',[], []);
										exit(0);
									}else{
										if($permission_allow === 2){
											if(($from_time !== $in_time) && ($to_time !== $out_time)){
                                                echo $this->returnResult(false,'Permission Only Allow Shift Start or Shift End Time.!',[], []);
												exit(0);
											}else{
												return true;
											}
										}else
										if($permission_allow === 1){
											return true;
										}
									}		
								}
							}
						}
					}else{
                        echo $this->returnResult(FALSE,"Don't Add Permission Request.! Payroll Already Processed for this Month.!",[], []);
					}
				}else{
                    echo $this->returnResult(FALSE,'Please Set Month Day for this Category.!',[], []);
				}
			}
		}else{
            echo $this->returnResult(FALSE,'Please Check in Permission Setting for All Required Details are Added or not.!',[], []);
		}
	}

    //PAYROLL PROCESS WISE SALARY START DATE AND END DATE GET
	public function tos_day_info($employee_code,$entry_parameter){
		//GTE DEFAULT FINANCIAL YEAR
		$financial_info         = $this->get_leave_financial_details();
		$prime_financial_id     = $financial_info[0]->prime_leave_financial_year_id;	
		$starting_date          = date('Y-m-d',strtotime($financial_info[0]->starting_date));	
		$ending_date            = date('Y-m-d',strtotime($financial_info[0]->ending_date));

		$emp_pick_arr           = $this->get_emp_data($employee_code);
		$doj                    = $emp_pick_arr[$employee_code]['date_of_joining'];	
		//TO CALL A TIME OFFICE SETTING BASED MONTH DAY QRY FUNCTION 
		$month_day_result       = $this->tos_day_qry_fun($entry_parameter);
		if($month_day_result){
			$day_conditions      = (int)$month_day_result[0]->day_conditions;
			$day_count           = $month_day_result[0]->day_count;
			$day_start           = "";
			$day_end             = "";
			$process_month       = "";
			$next_month          = "";

			$pay_posting_result  = $this->pay_process_mon_info($employee_code,$starting_date,$ending_date);
			$process_month       =  $pay_posting_result[0]->process_month;
			// print_r($process_month);die;
			$month_day_arr       = $this->min_max_date_fun($prime_financial_id,$starting_date,$ending_date,$day_conditions,$day_count,$month_day_result,$process_month);
			if($doj > date("Y-m-d",strtotime($month_day_arr['salary_start_date']))){ // For Inbetween salary date joiners
				$month_day_arr['salary_start_date'] = date("d-m-Y",strtotime($doj));
			}
			return $month_day_arr;
		}else{
			return false;
		}
	}

    public function pay_process_mon_info($employee_code,$starting_date,$ending_date){
		$where_emp_qry     = ''; 
		if($employee_code){
			$where_emp_qry = ' and cw_transactions.employee_code ="'.$employee_code.'"';
		}
		$pay_posting_qry     = 'SELECT role as category,date_format(MAX(str_to_date(CONCAT("01-", transactions_month), "%d-%m-%Y")) , "%m-%Y") AS process_month from cw_transactions where cw_transactions.trans_status = 1'.$where_emp_qry;
		// and date_format(str_to_date(CONCAT("01-", transactions_month), "%d-%m-%Y") , "%Y-%m-%d") >= "'.$starting_date.'"		
		$pay_posting_info    = $this->runQuery("$pay_posting_qry");
        $pay_posting_rslt    = $this->result_array($pay_posting_info);

		$process_month     = $pay_posting_rslt[0]['process_month'];
		if(!$process_month){
			//IF THIS EMPLOYEE WAS NEW JOINEE TO GET LAST PAYROLL MONTH
			return $this->last_pay_process_mon_info($starting_date,$ending_date);
		}else{
			$pay_posting_rslt[0] = (object)$pay_posting_rslt[0];
			return $pay_posting_rslt;
		}
	}

    public function last_pay_process_mon_info($starting_date,$ending_date){
		$last_pay_trans_qry  = 'SELECT role as category,date_format(MAX(str_to_date(CONCAT("01-", transactions_month), "%d-%m-%Y")) , "%m-%Y") AS process_month from cw_transactions where cw_transactions.trans_status = 1 AND fandf != 1';
		// and date_format(str_to_date(CONCAT("01-", transactions_month), "%d-%m-%Y") , "%Y-%m-%d") >= "'.$starting_date.'"		
		$last_pay_trans_info = $this->runQuery("$last_pay_trans_qry");
        $last_pay_trans_rslt = $this->result_array($last_pay_trans_info);
		$process_month       = $last_pay_trans_rslt[0]['process_month'];
		if(!$process_month){
			//THERE IS NO ANY PAYROLL PROCESS MONTH THEN GET FINANCIAL START MONTH
			// $process_month_obj   = (object)array('process_month' => date('m-Y'));
			//THERE IS NO ANY PAYROLL PROCESS MONTH THEN GET FINANCIAL START MONTH
			$process_month_obj   = (object)array('process_month' => date('m-Y',strtotime($starting_date)));
			$process_month_arr   = array(0 => $process_month_obj);
			return $process_month_arr;
		}else{
			return $last_pay_trans_rslt;
		}
	}

    public function min_max_date_fun($prime_financial_id,$starting_date,$ending_date,$day_conditions,$day_count,$month_day_result,$process_month){
		if(!$process_month){		
			$process_month = date("m-Y",strtotime($starting_date));
			$day_start     = date('d',strtotime($starting_date));
			$day_end       = date('d',strtotime($ending_date));
			$next_month    = $process_month;
		}else{
			if((int)$day_conditions === 3){
				//GET LAST DATE FOR CUTTOFF TYPE ONLY
				$day_start     = $month_day_result[0]->day_start;
				$day_end       = $month_day_result[0]->day_end;		
				$next_month    = date('m-Y',strtotime("+1 month",strtotime("01-".$process_month)));			
			}else{
				$day_start     = '01';				
				$next_month    = date('m-Y',strtotime("+1 month",strtotime("01-".$process_month)));
				$day_end       = date('t',strtotime("01-".$next_month));
			}
		}
		
		$today_date        = date('d-m-Y');
		$salary_end_year   = "12-".date('Y');
		if($day_conditions === "" || $day_start === "" || $day_end === ""){
			return false;
		}else{
			if((int)$day_conditions === 3){
				$sal_start         = $day_start;
				//For Current month between days increment
				$date              = new DateTime("01-$next_month 00:00:00");
				$date->modify('-1 month');
				$salary_start_date = $date->format("$sal_start-m-Y");	
				$salary_end_date   = date('d-m-Y',strtotime("$day_end-".$next_month));
				$year_end_date     = date("d-m-Y",strtotime($ending_date));
			}else{
				$sal_start         = $day_start;
				$date              = new DateTime("01-$next_month 00:00:00");
				$salary_start_date = $date->format("$sal_start-m-Y");	
				$salary_end_date   = date("d-m-Y",strtotime($day_end."-".$next_month));
				$year_end_date     = date("d-m-Y",strtotime($ending_date));
			}
			
			$month_day_arr      = array("salary_start_date" => $salary_start_date,"salary_end_date" => $salary_end_date,"year_end_date" => $year_end_date,"starting_date" => $starting_date,"ending_date" => $ending_date);

			return $month_day_arr;
		}
	}

    public function shift_time_qry($shift_name){
		//CHECK FROM SHIFT MASTER FOR FROM TIME AND TO TIME VALIDATION QUERY
		$shift_master_qry        = 'SELECT * FROM cw_shift_master WHERE cw_shift_master.prime_shift_master_id = "'.$shift_name.'" and cw_shift_master.trans_status = 1';
        $shift_master_info       = $this->runQuery("$shift_master_qry");
		$shift_master_rslt       = $this->result_array($shift_master_info);
		return $shift_master_rslt;
	}

    # ROLE BASED [MS 22-11-2024]  
    public function role_based_fun($employee_code,$module,$user_right){
        $role_based_qry        = 'SELECT where_condition FROM cw_form_table_search WHERE query_module_id = "'.$module.'" AND FIND_IN_SET("'.$user_right.'",query_for) AND trans_status = "1"';
        $role_based_info       = $this->runQuery("$role_based_qry");
		$role_based_rslt       = $this->result_array($role_based_info);
        if(count($role_based_rslt ?? []) > 0){
            $role_condition    = str_replace('^@logged_emp_code@^',"'$employee_code'",$role_based_rslt[0]['where_condition']) ;
			$role_condition    = str_replace('^','"',$role_condition);
			$role_condition    = str_replace(',','","',$role_condition);
            return $role_condition;
        }else{
            return "";
        }
    }

    # MANUAL PUNCH SHIFT [MS 22-11-2024]
    public function manualPunchShift($json){
        $employee_code      = $json->code;
		$shift_date         = $json->shift_date; 
		$shift_time_qry     = 'select cw_shift_import.shift_name,cw_shift_import.shift_date as shift_date,cw_shift_master.shift_status,cw_shift_master.in_time as import_in_time,cw_shift_master.out_time as import_out_time,cw_shift_master.from_time as from_time,cw_shift_master.to_time as to_time,cw_shift_master.first_half as first_half,cw_shift_master.second_half as second_half from cw_shift_import inner join cw_shift_master on cw_shift_master.prime_shift_master_id = cw_shift_import.shift_name where cw_shift_import.employee_code = "'.$employee_code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.trans_status = 1';
		$shift_time_info    = $this->runQuery("$shift_time_qry");
		$shift_time_rslt    = $this->result_array($shift_time_info);
		if($shift_time_rslt){
			$min_date_time  = "";
			$max_date_time  = "";
			$min_date       = "";
			$min_time       = "";
			$max_date       = "";
			$max_time       = "";
			$mp_treat_time_log_qry        = 'SELECT mp_treat_as FROM cw_company_information WHERE trans_status = 1';
			$mp_treat_time_log_info       = $this->runQuery("$mp_treat_time_log_qry");
			$mp_treat_time_log_rslt       = $this->result($mp_treat_time_log_info);
			$mp_treat_time_log            = $mp_treat_time_log_rslt[0]->mp_treat_as;
			if((int)$mp_treat_time_log === 1){
				$time_entry_date_qry      = 'select punch_in as min_log_date,punch_out as max_log_date from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and att_date = "'.$shift_date.'" and cw_time_entry.trans_status = 1';
				$time_entry_date_info     = $this->runQuery("$time_entry_date_qry");
	        	$time_entry_date_rslt     = $this->result_array($time_entry_date_info);
				$min_date_time            = $time_entry_date_rslt[0]['min_log_date'];
				$max_date_time            = $time_entry_date_rslt[0]['max_log_date'];
				if($min_date_time !== NULL && $min_date_time !== "0000-00-00 00:00:00"){
					$min_date             = date("d-m-Y",strtotime($min_date_time));
					$min_time             = date("H:i",strtotime($min_date_time));
				}
				if($max_date_time !== NULL && $max_date_time !== "0000-00-00 00:00:00"){
					$max_date             = date("d-m-Y",strtotime($max_date_time));
					$max_time             = date("H:i",strtotime($max_date_time));
				}
			}
            $rslt  = ['shift_result' => $shift_time_rslt, 'min_date' => $min_date, 'min_time' => $min_time, 'max_date' => $max_date, 'max_time' => $max_time] ;
            return $this->returnResult(TRUE,'Success',$rslt, []);
		}else{
            return $this->returnResult(FALSE,'Shift not Allocated in this Date!',[], []);
		}
    }

    # CHANGE SHIFT VALIDATION
    public function changeShiftValidation($json){
        $employee_code         = $json->code;
		$current_shift         = $json->current_shift;
		$change_shift          = $json->change_shift; 
		$shift_date            = $json->shift_date; 
	
		//EMP DETAILS QRY
 		$emp_details_query     = 'SELECT role as category,gender,grade from cw_employees WHERE employee_code = "'. $employee_code .'" and trans_status = 1';
		$emp_details_info      = $this->runQuery("$emp_details_query");
        $emp_details_result    = $this->result_array($emp_details_info);	

 		$category              = $emp_details_result[0]['category'];
		$gender                = $emp_details_result[0]['gender'];
		$grade                 = $emp_details_result[0]['grade'];
		$shift_eligible_qry    = 'SELECT cw_shift_eligibility.to_shift FROM cw_shift_eligibility WHERE FIND_IN_SET("'.$category.'",cw_shift_eligibility.category) and FIND_IN_SET("'.$gender.'",cw_shift_eligibility.gender) and FIND_IN_SET("'.$grade.'",cw_shift_eligibility.grade) and cw_shift_eligibility.from_shift = "'.$current_shift.'" and cw_shift_eligibility.trans_status = 1';
		$shift_eligible_info   = $this->runQuery("$shift_eligible_qry");
        $shift_eligible_rslt   = $this->result_array($shift_eligible_info);	
       
		if(!count($shift_eligible_rslt ?? [])){
			$rslt = ["msg" => "Proceed"];
            return $this->returnResult(TRUE,'Success',$rslt, []);
		}else{
			$change_shift_arr  = array_column($shift_eligible_rslt ?? [],"to_shift");
			if(!in_array($change_shift, $change_shift_arr)){
                return $this->returnResult(FALSE,'Could not Change this Shift. Please Check Shift Eligibility..?',[], []);
			}else{
                $rslt = ["msg" => "Proceed"];
				return $this->returnResult(TRUE,'Success',$rslt, []);
			}
		}
    }

    # BULK APPROVE 
    public function bulkApprove($json){
		$validate_jwt          = $this->validate_jwt();
        $approve_ids           = $json->approveIds;
        $action                = $json->action;
        $leave_status          = $json->leave_status;
        $approve_ids           = implode('","',$approve_ids ?? []);
		$created_on            = date("Y-m-d H:i:s");
		$financial_info        = $this->get_leave_financial_details();
		$prime_financial_id    = $financial_info[0]->prime_leave_financial_year_id;
		$action_msg            = "";
        // $logged_id             = $_SESSION['logged_prime_employees_id'];
		//COMPANY INFORMATION DETAILS GET
		$company_info          = $this->company_info();
		$mp_treat_time_log     = $company_info[0]->mp_treat_as;
		if($action === "1"){ // APPROVE BASED CONDITION
			$action_msg        = "Successfully Approved.!";
		}else
		if($action === "2"){ // REJECT BASED CONDITION
			$action_msg        = "Successfully Rejected.!";
		}else{
			return $this->returnResult(FALSE,'Invalid Action..',[], []);
		}
		$approve_detail_qry    = 'select * from cw_approval where prime_approval_id in ("'.$approve_ids.'") and leave_status = 1  and trans_status = 1';
		$approve_detail_info   = $this->runQuery("$approve_detail_qry");
        $approve_detail_rslt   = $this->result_array($approve_detail_info);	
		$bulk_approve_arr      = array();
		foreach ($approve_detail_rslt as $app_key => $app_val) {
			$app_id            = $app_val['prime_approval_id'];
			$bulk_approve_arr[$app_id]  = $app_val;
		}
		if($bulk_approve_arr){
			$sts                      = true;
			$logged_id                = $validate_jwt->prime_employees_id;
			$logged_emp_code          = $validate_jwt->code;
			$approved_rows            = 0;
			foreach ($bulk_approve_arr as $key => $arr_value) {
				$prime_approval_id    = $arr_value['prime_approval_id'];
				$first_level          = $arr_value['first_level_approval'];
				$second_level         = $arr_value['second_level_approval'];
				$request_type         = $arr_value['request_type'];
				$approve_type         = (int)$arr_value['leave_approve_type'];
				$first_leave_status   = (int)$arr_value['first_approval_leave_status'];
				$second_leave_status  = (int)$arr_value['second_approval_leave_status'];
				$first_cancel_status  = (int)$arr_value['first_approval_cancel_status']; 
				$second_cancel_status = (int)$arr_value['second_approval_cancel_status'];
				$cancel_request       = (int)$arr_value['cancellation_request'];
				$from_date            = $arr_value['from_date'];
				$to_date              = $arr_value['to_date'];
				$shift_date           = $arr_value['shift_date'];
				$permission_date      = $arr_value['permission_date'];
				$employee_code        = $arr_value['employee_code'];
				$approve_date         = "";
				//leave status update based on first and second level
				if($cancel_request === 2){
					if($action === "1"){ // APPROVE
						if($logged_emp_code === $first_level){
							$first_leave_status   = 2;
						}
						if($logged_emp_code === $second_level){
							$second_leave_status  = 2;
						}
					}else
					if($action === "2"){ // REJECT
						if($logged_emp_code === $first_level){
							$first_leave_status   = 3;
						}
						if($logged_emp_code === $second_level){
							$second_leave_status  = 3;
						}
					}

					if($approve_type === 1){ //ANYONE
						if($first_leave_status === 2 || $second_leave_status  === 2){
							$leave_status     = 2;
							$approve_date     = date("Y-m-d");
						}else
						if($first_leave_status === 3 || $second_leave_status  === 3){
							$leave_status     = 3;
						}
					}else
					if($approve_type === 2){ //BOTH
						if($first_leave_status === 2 && $second_leave_status  === 2){
							$leave_status     = 2;
							$approve_date     = date("Y-m-d");
						}else
						if($first_leave_status === 3 && $second_leave_status  === 3){
							$leave_status     = 3;
						}else
						if($first_leave_status === 3 || $second_leave_status  === 3){
							$leave_status     = 3;
						}
					}else
					if($approve_type === 3){ //ONLY FIRST LEVEL
						if($first_leave_status === 2){
							$leave_status     = 2;
							$approve_date     = date("Y-m-d");
						}else
						if($first_leave_status === 3){
							$leave_status     = 3;
						}
					}else
					if($approve_type === 4){ //ONLY SECOND LEVEL
						if($second_leave_status === 2){
							$leave_status     = 2;
							$approve_date     = date("Y-m-d");
						}else
						if($second_leave_status === 3){
							$leave_status     = 3;
						}
					}		
				}else{					
					if($action === "1"){ // APPROVE
						if($logged_emp_code === $first_level){
							$first_cancel_status   = 2;
						}
						if($logged_emp_code === $second_level){
							$second_cancel_status  = 2;
						}
					}else
					if($action === "2"){ // REJECT
						if($logged_emp_code === $first_level){
							$first_cancel_status   = 3;
						}
						if($logged_emp_code === $second_level){
							$second_cancel_status  = 3;
						}
					}
					if($approve_type === 1){ //ANYONE
						if($first_cancel_status === 2 || $second_cancel_status  === 2){
							$leave_status         = 4;
							$approve_date         = date("Y-m-d");
						}else
						if($first_cancel_status === 3 || $second_cancel_status  === 3){
							$leave_status         = 2;
						}
					}else
					if($approve_type === 2){ //BOTH
						if($first_cancel_status === 2 && $second_cancel_status  === 2){
							$leave_status         = 4;
							$approve_date         = date("Y-m-d");
						}else
						if($first_cancel_status === 3 && $second_cancel_status  === 3){
							$leave_status         = 2;
						}else
						if($first_cancel_status === 3 || $second_cancel_status  === 3){
							$leave_status         = 3;
						}
					}else
					if($approve_type === 3){ //ONLY FIRST LEVEL
						if($first_cancel_status === 2){
							$leave_status         = 4;
							$approve_date         = date("Y-m-d");
						}else
						if($first_cancel_status === 3){
							$leave_status         = 2;
						}
					}else
					if($approve_type === 4){ //ONLY SECOND LEVEL
						if($second_cancel_status === 2){
							$leave_status         = 4;
							$approve_date         = date("Y-m-d");
						}else
						if($second_cancel_status === 3){
							$leave_status         = 2;
						}
					}		
				}
				// [MS 07-01-2025]
				$arr_value['first_approval_cancel_status']  = $first_cancel_status;
				$arr_value['second_approval_cancel_status'] = $second_cancel_status;

				//TO CHECK TIME ENTRY TABLE
				if($leave_status === 2 && $cancel_request === 2){
					if($request_type === "1" || $request_type === "2" || $request_type === "3" || $request_type === "7" || $request_type === "8" || $request_type === "4"){
						if($request_type === "4"){
							$success          = "true";
						}else{
							if((int)$request_type === 7 && (int)$mp_treat_time_log === 1){
								$time_log_rslt    = $this->time_log($arr_value,$prime_financial_id,$leave_status,$logged_id);
								$success          = $time_log_rslt['success'];
							}
						}
						if($success === "false"){
							$sts     = false;
							$msg     = $time_log_rslt['message'];
					 	}else{
							//APPROVAL UPD QUERY
							$approval_upd_qry    = 'UPDATE cw_approval SET first_approval_leave_status = "'.$first_leave_status.'",second_approval_leave_status = "'.$second_leave_status.'",leave_status = "'.$leave_status.'",approve_date = "'.$approve_date.'",trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'" WHERE prime_approval_id = "'.$prime_approval_id.'"';
							$approval_upd_info   = $this->runQuery("$approval_upd_qry");
							if($approval_upd_info){
								//TO UPDATE A REQUEST AND THIS REQUEST TYPE RELATED ENTRY MODULE
								if($request_type === "1" || $request_type === "2" || $request_type === "3" || $request_type === "8"){	
									$this->approval_process($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
								}else
								if($request_type === "4" || $request_type === "5"){
									$this->permission_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
								}
								else
								if($request_type === "7"){
									$this->manual_punch_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
								}
								$approved_rows++;
							}
						}
					}else
					if($request_type === "6"){
						//THIS IS NOT SAME AS OTHER REQUEST 
						//APPROVAL UPD QUERY
						$approval_upd_qry    = 'UPDATE cw_approval SET first_approval_leave_status = "'.$first_leave_status.'",second_approval_leave_status = "'.$second_leave_status.'",leave_status = "'.$leave_status.'",approve_date = "'.$approve_date.'",trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'" WHERE prime_approval_id = "'.$prime_approval_id.'"';
						$approval_upd_info   = $this->runQuery("$approval_upd_qry");
						if($approval_upd_info){
							$this->shift_change_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
							$approved_rows++;
						}
					}
				}else{
					//APPROVAL UPD QUERY
					$approval_upd_qry    = 'UPDATE cw_approval SET first_approval_leave_status = "'.$first_leave_status.'",second_approval_leave_status = "'.$second_leave_status.'",leave_status = "'.$leave_status.'",approve_date = "'.$approve_date.'",trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'" WHERE prime_approval_id = "'.$prime_approval_id.'"';
					$approval_upd_info   = $this->runQuery("$approval_upd_qry");
					if($approval_upd_info){
						//TO UPDATE A REQUEST AND THIS REQUEST TYPE RELATED ENTRY MODULE
						if($request_type === "1" || $request_type === "2" || $request_type === "3" || $request_type === "8"){	
							$this->approval_process($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
						}else
						if($request_type === "4" || $request_type === "5"){
							$this->permission_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
						}else
						if($request_type === "6"){
							$this->shift_change_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
						}else
						if($request_type === "7"){
							$this->manual_punch_approval($arr_value,$prime_approval_id,$prime_financial_id,$first_leave_status,$second_leave_status,$leave_status,$logged_id);
						}
						$approved_rows++;
					}
				}
			}
			if($sts){
				//TIME ENTRY PROCEDURE CALLING				
				$shift_date_arr      = array("4","6","7");
				if(in_array($request_type,$shift_date_arr)){
					if($request_type === "4" || $request_type === "5"){
						$this->runQuery("CALL itsp_prcatt ('$permission_date','$permission_date','$employee_code')");
					}else{
						$this->runQuery("CALL itsp_prcatt ('$shift_date','$shift_date','$employee_code')");
					}					
				}else{
					$this->runQuery("CALL itsp_prcatt ('$from_date','$to_date','$employee_code')");
				}
                return $this->returnResult(True,"$action_msg",[], []);
			}else{
				//ALL SELECTED ROWS ERROR
				if($approved_rows === 0){
                    return $this->returnResult(FALSE,"Data Already Exist in Time Entry Table.!",[], []);
				}else{
                    return $this->returnResult(FALSE,"$action_msg But $msg",[], []);
				}
			}
		}else{
            return $this->returnResult(FALSE,"Unable to Approve. Some Data Already Approved or Could not able to Approve.!",[], []);
		}
    }

    # COMPANY INFO
    public function company_info(){
		$company_qry    = 'select * from cw_company_information where cw_company_information.trans_status = 1';
		$company_info   = $this->runQuery("$company_qry");
        $company_rslt   = $this->result($company_info);	
		return $company_rslt;
	}

    # APPROVAL PROCESS
    public function approval_process($post_data,$form_id,$prime_financial_id,$first_approval,$second_approval,$leave_status,$logged_id){
		$created_on           = date("Y-m-d h:i:s");
		foreach ($post_data as $key => $value) {
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "prime_request_id"){
				$prime_request_id = $value;
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_type"){
				$leave_type = $value;
			}
			if($key === "rejected_reason"){
				$rejected_reason = $value;
			}
			if($key === "no_of_days"){
				$no_of_days = $value;
			}
			if($key === "cancellation_request"){
				$cancellation_request = $value;
			}
			if($key === "first_approval_cancel_status"){
				$first_approval_cancel_status = $value;
			}
			if($key === "second_approval_cancel_status"){
				$second_approval_cancel_status = $value;
			}
		}
		$leave_creation_qry    = 'SELECT leave_opening,intervening_holidays,leave_name from cw_leave_creation where cw_leave_creation.trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
		$leave_creation_info   = $this->runQuery("$leave_creation_qry");
        $leave_creation_rslt   = $this->result_array($leave_creation_info);	
		$leave_opening  	   = $leave_creation_rslt[0]['leave_opening'];
		$leave_name  		   = $leave_creation_rslt[0]['leave_name'];
		$leave_name 		   = strtolower($leave_name);
		$pending_column 	   = "pending_".$leave_name;
		$used_column 	   	   = "used_".$leave_name;

		$employee_detail_qry  			  = 'select prime_employees_id,company_email_id from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info             = $this->runQuery("$employee_detail_qry");
        $employee_detail_rslt             = $this->result_array($employee_detail_info);	
		$view_id 						  = $employee_detail_rslt[0]['prime_employees_id'];
		$employee_to_mail 				  = $employee_detail_rslt[0]['company_email_id'];
		$print_type_id                    = '';
		if((int)$cancellation_request === 1){
			if((int)$leave_status === 4){
				if((int)$leave_opening === 1){
					$leave_opening_qry 			= 'select '.$used_column.' from cw_leave_opening where employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and trans_status = 1';
					$leave_opening_info         = $this->runQuery("$leave_opening_qry");
                    $leave_opening_result       = $this->result_array($leave_opening_info);	
					$used   					= $leave_opening_result[0][$used_column];
					$leave_total 				= $used - $no_of_days;

					$upd_leave_opening = 'UPDATE cw_leave_opening SET '.$used_column.' = "'.$leave_total.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and cw_leave_opening.trans_status = 1';
					$this->runQuery("$upd_leave_opening");
				}
				if((int)$request_type === 1){
					$upd_leave_entry = 'UPDATE cw_leave_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_leave_entry.trans_status = 1';
					$this->runQuery("$upd_leave_entry");
					//FOR EMAIL
					$print_type_id = 25;
				}else
				if((int)$request_type === 3 || (int)$request_type === 8){
					$upd_on_duty_entry = 'UPDATE cw_on_duty_entry SET on_duty_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_on_duty_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_on_duty_entry.trans_status = 1';
					$this->runQuery("$upd_on_duty_entry");
					//FOR EMAIL
					$print_type_id = 37;
				}
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//EMAIL SEND FUNCTION
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//FOR EMAIL
				if((int)$request_type === 1){
					$print_type_id = 26;
				}else
				if((int)$request_type === 3 || (int)$request_type === 8){
					$print_type_id = 38;
				}
				//EMAIL SEND FUNCTION
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}
		}else{	
			if((int)$leave_status === 2){
				if((int)$leave_opening === 1){
					$leave_opening_qry 			= 'select '.$used_column.','.$pending_column.' from cw_leave_opening where employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and trans_status = 1';
					$leave_opening_info         = $this->runQuery("$leave_opening_qry");
                    $leave_opening_result       = $this->result_array($leave_opening_info);	
					$used   					= $leave_opening_result[0][$used_column];
					$pending    				= $leave_opening_result[0][$pending_column];
					$leave_total 				= $used + $no_of_days;
					$pending_total 				= $pending - $no_of_days;

					$upd_leave_opening = 'UPDATE cw_leave_opening SET '.$used_column.' = "'.$leave_total.'",'.$pending_column.' = "'.$pending_total.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and cw_leave_opening.trans_status = 1';
					$this->runQuery("$upd_leave_opening");
				}
				if((int)$request_type === 1){
					$upd_leave_entry = 'UPDATE cw_leave_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_leave_entry.trans_status = 1';
					$this->runQuery("$upd_leave_entry");
					//FOR EMAIL
					$print_type_id = 22;
				}else
				if((int)$request_type === 3 || (int)$request_type === 8){
					$upd_on_duty_entry = 'UPDATE cw_on_duty_entry SET on_duty_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_on_duty_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_on_duty_entry.trans_status = 1';
					$this->runQuery("$upd_on_duty_entry");
					//FOR EMAIL
					$print_type_id = 34;
				}
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				
				//EMAIL SEND FUNCTION
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else
			if((int)$leave_status === 3){
				if((int)$leave_opening === 1){
					$leave_opening_qry 			= 'select '.$pending_column.' from cw_leave_opening where employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and trans_status = 1';
					$leave_opening_info         = $this->runQuery("$leave_opening_qry");
                    $leave_opening_result       = $this->result_array($leave_opening_info);	
					$pending    				= $leave_opening_result[0][$pending_column];
					$pending_total 				= $pending - $no_of_days;

					$upd_leave_opening = 'UPDATE cw_leave_opening SET '.$pending_column.' = "'.$pending_total.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_financial_id.'" and cw_leave_opening.trans_status = 1';
					$this->runQuery("$upd_leave_opening");
				}

				if((int)$request_type === 1){
					$upd_leave_entry = 'UPDATE cw_leave_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_leave_entry.trans_status = 1';
					$this->runQuery("$upd_leave_entry");
					//FOR EMAIL
					$print_type_id = 23;
				}else
				if((int)$request_type === 3 || (int)$request_type === 8){
					$upd_on_duty_entry = 'UPDATE cw_on_duty_entry SET on_duty_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_on_duty_entry.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_on_duty_entry.trans_status = 1';
					$this->runQuery("$upd_on_duty_entry");
					//FOR EMAIL
					$print_type_id = 35;
				}
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",rejected_reason = "'.$rejected_reason.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//EMAIL SEND FUNCTION
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
			}
		}
	}

    # 
    public function permission_approval($post_data,$form_id,$prime_financial_id,$first_approval,$second_approval,$leave_status,$logged_id){
		$created_on           = date("Y-m-d h:i:s");
		foreach ($post_data as $key => $value) {
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "prime_request_id"){
				$prime_request_id = $value;
			}
			if($key === "leave_type"){
				$leave_type = $value;
			}
			if($key === "rejected_reason"){
				$rejected_reason = $value;
			}
			if($key === "no_of_days"){
				$no_of_days = $value;
			}
			if($key === "cancellation_request"){
				$cancellation_request = $value;
			}
			if($key === "first_approval_cancel_status"){
				$first_approval_cancel_status = $value;
			}
			if($key === "second_approval_cancel_status"){
				$second_approval_cancel_status = $value;
			}
			if($key === "permission_date"){
				$permission_date = $value;
			}
		}
		
		$permission_date_format           = date("Y-m-d",strtotime($permission_date));

		$employee_detail_qry  			  = 'select prime_employees_id,company_email_id from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info             = $this->runQuery("$employee_detail_qry");
        $employee_detail_result           = $this->result_array($employee_detail_info);	
		$view_id 						  = $employee_detail_result[0]['prime_employees_id'];
		$employee_to_mail 				  = $employee_detail_result[0]['company_email_id'];
		if((int)$cancellation_request === 1){
			if((int)$leave_status === 4){
				$upd_permission_entry = 'UPDATE cw_permission_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.prime_request_id = "'.$prime_request_id.'" and cw_permission_entry.trans_status = 1';
				$this->runQuery("$upd_permission_entry");

				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				
				$print_type_id = 31;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				$print_type_id = 32;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}
		}else{
			if((int)$leave_status === 2){
				$upd_permission_entry   = 'UPDATE cw_permission_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.prime_request_id = "'.$prime_request_id.'" and cw_permission_entry.trans_status = 1';
				$this->runQuery("$upd_permission_entry");
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$upd_res = $this->runQuery("$upd_request");

				if($upd_res){
					$print_type_id = 28;
					$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
				}
				/*if($result){
					
				}*/				
			}else
			if((int)$leave_status === 3){
				$upd_permission_entry = 'UPDATE cw_permission_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.prime_request_id = "'.$prime_request_id.'" and cw_permission_entry.trans_status = 1';
				$this->runQuery("$upd_permission_entry");

				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",rejected_reason = "'.$rejected_reason.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");

				$print_type_id = 29;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
			}
		}
	}
    
    # 
    public function shift_change_approval($post_data,$form_id,$prime_financial_id,$first_approval,$second_approval,$leave_status,$logged_id){
		$created_on           = date("Y-m-d h:i:s");
		foreach ($post_data as $key => $value) {
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "prime_request_id"){
				$prime_request_id = $value;
			}
			if($key === "shift_date"){
				$shift_date = $value;
			}
			if($key === "current_shift"){
				$current_shift = $value;
			}
			if($key === "change_shift"){
				$change_shift = $value;
			}
			if($key === "rejected_reason"){
				$rejected_reason = $value;
			}
			if($key === "cancellation_request"){
				$cancellation_request = $value;
			}
			if($key === "first_approval_cancel_status"){
				$first_approval_cancel_status = $value;
			}
			if($key === "second_approval_cancel_status"){
				$second_approval_cancel_status = $value;
			}
		}
		$employee_detail_qry  			  = 'select prime_employees_id,company_email_id from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info             = $this->runQuery("$employee_detail_qry");
        $employee_detail_result           = $this->result_array($employee_detail_info);	
		$view_id 						  = $employee_detail_result[0]['prime_employees_id'];
		$employee_to_mail 				  = $employee_detail_result[0]['company_email_id'];
		
		if((int)$cancellation_request === 1){
			if((int)$leave_status === 4){
				$upd_shift_import = 'UPDATE cw_shift_import SET shift_name = "'.$current_shift.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_shift_import.employee_code = "'.$employee_code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.trans_status = 1';
				$upd_shift_id     = $this->runQuery("$upd_shift_import");
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");

				//function for run a time entry because shift will update
				//$this->time_entry_process($employee_code,$shift_date,$current_shift);
				//FOR EMAIL
				$print_type_id = 43;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//FOR EMAIL
				$print_type_id = 44;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}
		}else{
			if((int)$leave_status === 2){
				$upd_shift_import = 'UPDATE cw_shift_import SET shift_name = "'.$change_shift.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_shift_import.employee_code = "'.$employee_code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.trans_status = 1';
				$upd_shift_id     = $this->runQuery("$upd_shift_import");
				$upd_request      = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");

				//function for run a time entry because shift will update
				//$this->time_entry_process($employee_code,$shift_date,$change_shift);
				
				//FOR EMAIL
				$print_type_id = 40;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else
			if((int)$leave_status === 3){
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",rejected_reason = "'.$rejected_reason.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//FOR EMAIL
				$print_type_id = 41;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				
				$this->runQuery("$upd_request");
			}
		}
	}

    #
    public function manual_punch_approval($post_data,$form_id,$prime_financial_id,$first_approval,$second_approval,$leave_status,$logged_id){
		$created_on           = date("Y-m-d h:i:s");
		foreach ($post_data as $key => $value) {
			if($key === "component_value"){
				$component_value = $value;
			}
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "shift_date"){
				$shift_date  = $value;
			}
			if($key === "shift_name"){
				$shift_name = $value;
			}
			if($key === "in_date"){
				$in_date = $value;
			}
			if($key === "out_date"){
				$out_date = $value;
			}
			if($key === "day_type"){
				$day_type = $value;
			}
			if($key === "in_time"){
				$in_time = $value;
			}
			if($key === "out_time"){
				$out_time = $value;
			}
			if($key === "total_time"){
				$total_time = $value;
			}
			if($key === "prime_request_id"){
				$prime_request_id = $value;
			}
			if($key === "rejected_reason"){
				$rejected_reason = $value;
			}
			if($key === "cancellation_request"){
				$cancellation_request = $value;
			}
			if($key === "first_approval_cancel_status"){
				$first_approval_cancel_status = $value;
			}
			if($key === "second_approval_cancel_status"){
				$second_approval_cancel_status = $value;
			}
		}
		$from_date_time     = $in_date." ".$in_time;
		$to_date_time       = $out_date." ".$out_time;
		$employee_detail_qry  			  = 'select prime_employees_id,company_email_id,device_code from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info             = $this->runQuery("$employee_detail_qry");
        $employee_detail_result           = $this->result_array($employee_detail_info);	
		$view_id 						  = $employee_detail_result[0]['prime_employees_id'];
		$employee_to_mail 				  = $employee_detail_result[0]['company_email_id'];
		$device_code     				  = $employee_detail_result[0]['device_code'];
		if((int)$cancellation_request === 1){
			if((int)$leave_status === 4){
				$upd_manual_punch_entry = 'UPDATE cw_manual_punch_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_manual_punch_entry.employee_code = "'.$employee_code.'" and cw_manual_punch_entry.prime_request_id = "'.$prime_request_id.'" and cw_manual_punch_entry.trans_status = 1';
				$this->runQuery("$upd_manual_punch_entry");

				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				
				$del_time_log_qry   = 'DELETE FROM cw_time_log WHERE cw_time_log.user_id = "'.$device_code.'" and cw_time_log.device_id in ("MAN01","MAN02") and log_date in ("'.$from_date_time.'","'.$to_date_time.'")';
				$this->runQuery("$del_time_log_qry");
				//FOR EMAIL
				$print_type_id = 49;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_cancel_status = "'.$first_approval_cancel_status.'",second_approval_cancel_status = "'.$second_approval_cancel_status.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//FOR EMAIL
				$print_type_id = 50;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}
		}else{
			if((int)$leave_status === 2){
				$upd_manual_punch_entry = 'UPDATE cw_manual_punch_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_manual_punch_entry.employee_code = "'.$employee_code.'" and cw_manual_punch_entry.prime_request_id = "'.$prime_request_id.'" and cw_manual_punch_entry.trans_status = 1';
				$this->runQuery("$upd_manual_punch_entry");
				 
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request"); 
				//FOR EMAIL
				$print_type_id = 46;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else
			if((int)$leave_status === 3){
				//Manual punch upd query
				$upd_manual_punch_entry = 'UPDATE cw_manual_punch_entry SET leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_manual_punch_entry.employee_code = "'.$employee_code.'" and cw_manual_punch_entry.prime_request_id = "'.$prime_request_id.'" and cw_manual_punch_entry.trans_status = 1';
				$this->runQuery("$upd_manual_punch_entry");

				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",rejected_reason = "'.$rejected_reason.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
				//FOR EMAIL
				$print_type_id = 47;
				$this->send_mail($print_type_id,$form_id,$employee_to_mail,$logged_id);
			}else{
				$upd_request = 'UPDATE cw_request SET first_approval_leave_status = "'.$first_approval.'",second_approval_leave_status = "'.$second_approval.'",leave_status = "'.$leave_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_request.employee_code = "'.$employee_code.'" and prime_request_id = "'.$prime_request_id.'" and cw_request.trans_status = 1';
				$this->runQuery("$upd_request");
			}
		}
	}

    #
    public function send_mail($print_type_id,$view_id,$employee_to_mail,$logged_id){
		// $email_data     	  = $this->load_email_data($print_type_id,$view_id,$logged_id);
        // $logged_role          = $_SESSION['logged_emp_role'];
		// $body_content   	  = "<!DOCTYPE html><html> <body>".$email_data['print_design']."</body></html>";
		// $email_design_query   = 'select prime_print_info_id,email_design,print_info_for,print_info_module_id,print_type,email_subject,email_bcc,to_email from cw_email_design inner join cw_print_info on cw_print_info.prime_print_info_id = cw_email_design.email_design_for where find_in_set("'.$logged_role.'",print_info_for) and print_info_module_id = "approval" and cw_print_info.trans_status = 1 and print_type = "'.$print_type_id.'"';

		// $email_design_info        = $this->runQuery("$email_design_query");
        // $email_design_result      = $this->result_array($email_design_info);	
		// $email_design_content     = $email_design_result[0]['email_design'];
		// $mail_subject             = $email_design_result[0]['email_subject'];
		// $email_bcc 			      = $email_design_result[0]['email_bcc'];
		// $to_email 			      = $email_design_result[0]['to_email'];
		// $email_returns            = $this->send_email_notification($to_email,$employee_to_mail,'',$email_bcc,$mail_subject,$body_content,'');
		return true;
	}

    #
    public function load_email_data($email_doc_id,$view_id,$logged_id){
		$data['print_sts']    = false;
		$design_qry           = 'select email_design,print_type,email_design_for from cw_email_design inner join cw_print_info on cw_print_info.prime_print_info_id=cw_email_design.email_design_for where print_type = "'.$email_doc_id.'" and cw_print_info.trans_status = 1';
		$design_info          = $this->runQuery("$design_qry");
        $design_result        = $this->result_array($design_info);	
		$print_design         = $design_result[0]['email_design'];
		$print_type           = $design_result[0]['print_type'];
		$email_design_for     = $design_result[0]['email_design_for'];
		$style  = "<style>
		table{
			border: 1px !important;
			border-collapse: collapse !important;
			empty-cells: show !important;
			max-width: 100% !important;
			font-size: 13px !important;
		}
		tbody {
			border: 1px !important;
			border-collapse: collapse !important; 
			empty-cells: show !important;
			max-width: 100% !important;
			font-size: 13px !important;
		}
		td, th {
			border: 1px solid #000 !important;
			font-size: 13px !important;
		}
		td.fr-thick,th.fr-thick {
			border-width: 2px !important;
		}
		table.fr-dashed-borders td, table.fr-dashed-borders th {
			border-style: dashed !important;
		}
		</style>";
		$print_design   = $style."".$print_design;
		$print_design   = str_replace('~','"',$print_design);
		$block_qry      = 'select * from cw_print_block where print_block_for = "'.$email_design_for.'" and trans_status = 1';
		$block_info     = $this->runQuery("$block_qry");
        $block_result   = $this->result_array($block_info);	
		foreach($block_result as $block){
			$prime_print_block_id  = $block->prime_print_block_id;
			$print_block_name      = $block->print_block_name;
			$print_block_type      = (int)$block->print_block_type;
			$print_block_table     = $block->print_block_table;
			$print_block_column    = $block->print_block_column;
			$suppressed_data       = $block->suppressed_data;
			$cumulative_data       = $block->cumulative_data;

			$table_qry             = 'select * from cw_print_table where print_table_for_id = "'.$prime_print_block_id.'" and trans_status = 1';
			$table_info            = $this->runQuery("$table_qry");
            $table_result          = $this->result_array($table_info);	
			$line_table_query      = "";
			$cutome_table_check    = array('transactions'=>'cw_transactions');
			foreach($table_result as $table){
				$line_prime_table      = $table->line_prime_table;
				$line_prime_col        = $table->line_prime_col;
				$line_join_type        = $table->line_join_type;
				$line_join_table       = $table->line_join_table;
				$line_join_col         = $table->line_join_col;
				$line_sort             = $table->line_sort;
				$module_name           = str_replace("cw_","",$line_prime_table);
				$prime_id              = "prime_".$module_name."_id";
				$join_module_name      = str_replace("cw_","",$line_join_table);
				$join_prime_id         = "prime_".$join_module_name."_id";
				if((int)$line_sort === 1){
					if($cutome_table_check[$module_name]){
						$line_prime_table = " $line_prime_table ";
					}else{
						$line_prime_table = " $line_prime_table ";
					}
					if($cutome_table_check[$join_module_name]){
						$line_join_table = " $line_join_table on $line_join_col = $line_prime_col";
					}else{
						$line_join_table = " $line_join_table on $line_join_col = $line_prime_col ";
					}
					$line_table_query .= " $line_prime_table  $line_join_type join $line_join_table"; 
				}else{
					if($cutome_table_check[$join_module_name]){
						$line_table_query .= " $line_join_type join $line_join_table on $line_join_col = $line_prime_col "; 
					}else{
						$line_table_query .= " $line_join_type join $line_join_table on $line_join_col = $line_prime_col "; 
					}
				}
			}
			if(!$line_table_query){
				$module_name      = str_replace("cw_","",$print_block_table);
				$prime_id         = "prime_".$module_name."_id";
				$line_table_query = " $print_block_table ";
			}

			if(!$print_block_column){
				$print_block_column = "*";
			}else{
				$select_query = "";
				$select_ytd_query = "";
				$pick_query   = "";
				$map_column = explode(",",$print_block_column ?? "");
				foreach($map_column as $table_column){
					$map_column   = explode(".",$table_column ?? "");
					$table_name   = $map_column[0];
					$column 	  = $map_column[1];
					$control_name = str_replace('cw_',"",$table_name);
					if($control_name === "transactions"){
						$control_name = "employees";
					}
					$form_qry    = 'select prime_form_id,view_name,label_name,field_type,pick_list_type,pick_list,pick_table,auto_prime_id,auto_dispaly_value from cw_form_setting where prime_module_id = "'.$control_name.'" and  label_name = "'.$column.'"  and trans_status = "1"';
					$form_info          = $this->runQuery("$form_qry");
                    $form_result        = $this->result_array($form_info);	
					foreach($form_result as $form){
						$prime_form_id  = (int)$form->prime_form_id;
						$view_name      = $form->view_name;
						$label_name     = $form->label_name;
						$field_type     = (int)$form->field_type;
						$pick_list_type = (int)$form->pick_list_type;
						$pick_list      = $form->pick_list;
						$pick_table     = $form->pick_table;
						$auto_prime_id      = $form->auto_prime_id;
						$auto_dispaly_value = $form->auto_dispaly_value;
						if((int)$field_type === 4){
							$select_query .= 'DATE_FORMAT('.$table_name.'.'.$label_name.', "%d-%m-%Y") as '.$label_name.' , ';
						}else
						if(($field_type === 5) || ($field_type === 7)){
							if($pick_list_type === 1){
								$pick_list_val   = explode(",",$pick_list ?? "");
								$pick_list_val_1 = $pick_list_val[0];
								$pick_list_val_2 = $pick_list_val[1];
								
								$pick_query_as = $pick_table."_".$prime_form_id;
								$select_query .= "$pick_query_as.$pick_list_val_2 as $label_name , ";
								$pick_query .= " left join $pick_table as $pick_query_as on $pick_query_as.$pick_list_val_1 = $table_name.$label_name ";
							}else
							if($pick_list_type === 2){ 
								$pick_list_val_1 = $pick_table."_id";
								$pick_list_val_2 = $pick_table."_value";
								$pick_list_val_3 = $pick_table."_status";
								
								$pick_query_as = $pick_table."_".$prime_form_id;
								$select_query .= "$pick_query_as.$pick_list_val_2 as $label_name , ";
								$pick_query   .= " left join $pick_table as $pick_query_as on $pick_query_as.$pick_list_val_1 = $table_name.$label_name ";
							}
						}else
						if($field_type === 9){
							$pick_query_as = $pick_table."_".$prime_form_id;
							$select_query .= "$pick_query_as.$auto_dispaly_value as $label_name,";
							$pick_query .= " left join $pick_table as $pick_query_as on $pick_query_as.$auto_prime_id = $table_name.$label_name ";
						}else
						if(($field_type === 2) || ($field_type === 3)){
							$label_ytd  =	$label_name."_ytd";
							$select_ytd_query .= "sum($table_name.$label_name) as $label_ytd, ";
							$select_query .= "$table_name.$label_name , ";
						}else{
							$select_query .= "$table_name.$label_name , ";
						}
					}					
				}
			}
			$where_trans = "";
			$where_trans_info = explode(",",$print_block_table ?? "");
			foreach($where_trans_info as $trans_info){
				if($trans_info === "cw_transactions"){
					$select_query .= "cw_transactions.transactions_month , ";
				}				
				$where_trans .= "$trans_info.trans_status = 1 and ";
			}
			$where_trans = rtrim($where_trans,'and ');
			$where_qry          = 'select * from cw_print_table_where where where_for_id = "'.$prime_print_block_id.'" and trans_status = 1';
			$where_info         = $this->runQuery("$where_qry");
            $where_result       = $this->result($where_info);	
			$where_condition    = "";
			if($where_result){
				$where_condition = str_replace('^','"',$where_result[0]->where_condition);
				$where_condition = str_replace('@logged_id@',$logged_id,$where_condition);				
				$session_date_list  = array("logged_DMY"=>"d-m-Y","logged_YMD"=>"Y-m-d","logged_MY"=>"m-Y","logged_YM"=>"Y-m","logged_Y"=>"Y"); 
				$session_query      = 'select session_value from cw_session_value where session_for = 1 and trans_status = "1"';
				$session_info       = $this->runQuery("$session_query");
                $session_result     = $this->result_array($session_info);	
				foreach($session_result as $rslt){
					$session_value 	   = $rslt->session_value;
					if($session_value !== "access_data"){
						$exist_val = "@".$session_value."@";
						if($session_date_list[$session_value]){
							$date_formate      = $session_date_list[$session_value];
							$saved_session_val = date($date_formate);
						}else{
							// $saved_session_val = $this->set_session_value("",$session_value);
						}
						$where_condition  = str_replace($exist_val,$saved_session_val,$where_condition);
					}
				}
			}
			$select_query = rtrim($select_query,',');
			$select_query = rtrim($select_query,' , ');
			if((int)$cumulative_data === 1){
                $financial_info = $this->get_leave_financial_details();
				$start_fin_date = $financial_info[0]->start_date;
				$start_fin_date = date('m-Y',strtotime($start_fin_date));
				$end_fin_date   = $financial_info[0]->end_date;
				$end_fin_date   = date('m-Y',strtotime($end_fin_date));
				$select_ytd_query = rtrim($select_ytd_query,',');
				$select_ytd_query = rtrim($select_ytd_query,' , ');
				$where_ytd_condition  = ' and date_format(str_to_date(transactions_month, "%m-%Y") , "%Y-%m")  >= date_format(str_to_date("'.$start_fin_date.'", "%m-%Y"), "%Y-%m") and date_format(str_to_date(transactions_month, "%m-%Y") , "%Y-%m")  <= date_format(str_to_date("'.$end_fin_date.'", "%m-%Y"), "%Y-%m")';
				$final_ytd_qry        = "select $select_ytd_query from $line_table_query $pick_query  where $where_trans $where_condition  $where_ytd_condition";
				$final_ytd_info       = $this->runQuery("$final_ytd_qry");
                $final_ytd_result     = $this->result_array($final_ytd_info);	
				foreach($final_ytd_result as $ytd_rslt){
					$map_column       = explode(",",$print_block_column ?? "");
					foreach($map_column as $table_column){
						$map_column   = explode(".",$table_column ?? "");
						$ytd_column 	  = $map_column[1]."_ytd";
						$ytd_value        = $ytd_rslt->$ytd_column;
						$replace_ytd_val  = "@".$ytd_column."@";
						$print_design  = str_replace($replace_ytd_val,$ytd_value,$print_design);
					}
				}
			}
			$final_qry       = "select $select_query from ".$line_table_query." $pick_query where $prime_id = ".$view_id." and  $where_trans $where_condition";
			$final_info      = $this->runQuery("$final_qry");
            $final_result    = $this->result($final_info);
			$tr_line = "";
			$th_line = "";
			$count = 0;
			$assign_date_formate_list  = array("DMY"=>"d-m-Y","YMD"=>"Y-m-d","DFY"=>"d F Y","MY"=>"F-Y","YM"=>"Y-F","D"=>"d","M"=>"M","Y"=>"Y");
			$split_qry            = 'select * from cw_print_split where trans_status = 1 and split_table_info ="'.$print_doc_id.'"';
			$split_info           = $this->runQuery("$split_qry");
            $split_result         = $this->result($split_info);
			$split_array = array();
			foreach($split_result as $split){
				$split_info  = $split->split_info;
				$split_colum = $split->split_colum;
				$split_array[$split_colum] = $split_info;
			}		
			if($final_result){
				$data['print_sts'] = true;
				foreach($final_result as $rslt){
					$count++;
					$map_column = explode(",",$print_block_column ?? "");
					$td_line = "";
					foreach($map_column as $table_column){
						$map_column   = explode(".",$table_column ?? "");
						$column 	  = $map_column[1];
						$value        = $rslt->$column;
						$replace_val  = "@".$column."@";
						//amount number is changed to in words for net pays--07SEP2019
						if($column == 'employee_code'){
							$value         = $rslt->$column;
							$print_design  = str_replace($replace_val,$value,$print_design);
							//DR CODE START *
							$application_url = site_url();
							$application_link = "<a href='$application_url'> Application Link </a>";
							$print_design  = str_replace("@application_link@",$application_link,$print_design);
							//FOR APPROVE LEAVE REQUEST
							$app_url       = $application_url.'/app/api_controller.php';
							$approve_link  = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
							<!DOCTYPE html>
							  <button class='btn btn-primary btn-sm' id= 'approve' onclick = 'approve()'>Approve</button>
							</html>
							<script>
								function approve(){
									alert();
									var send_url = '$app_url'; 
									$.ajax({
										type: 'POST',
										url: send_url,
										data:{frm:approve,view_id:$view_id},
										success: function(data) {
											console.log(data);
										}
									});
								}
							</script>";
							$print_design  = str_replace("@approve@",$approve_link,$print_design);
							//FOR REJECT LEAVE REQUEST
							$reject_link  = "<form>
											  <button class='btn btn-primary btn-sm' id= 'reject' onclick = 'reject()'>Reject</button>
											</form>
											<script>
												function reject(){
													var send_url = '$app_url'; 
													$.ajax({
														type: 'POST',
														url: send_url,
														data:{frm:reject,view_id:$view_id},
														success: function(data) {
													
														}
													});
												}
											</script>";
							$print_design  = str_replace("@reject@",$reject_link,$print_design);
							//DR CODE END *

						}else
						if($column == 'net_pay'){
							$value         = $rslt->$column;
							$print_design  = str_replace($replace_val,$value,$print_design);
							$net_pay_val   = $value;
							$net_pay_words = $this->numbertowords($net_pay_val);
							$net_pay_words = strtoupper($net_pay_words);
							$print_design  = str_replace("@net_pay_words@",$net_pay_words,$print_design);
						}else
						if($column == 'employee_name'){
							$value         = ucwords($rslt->$column);
							$print_design  = str_replace($replace_val,$value,$print_design);
						}else
						if($column == 'reporting_person'){
							$value         = ucwords($rslt->$column);
							$print_design  = str_replace($replace_val,$value,$print_design);
						}else
						if($column == 'salary'){
							$value         = $rslt->$column;
							$print_design  = str_replace($replace_val,$value,$print_design);
							$salary_val   = $value;
							$salary_words = $this->numbertowords($salary_val);
							$salary_words = ucwords($salary_words);
							$print_design  = str_replace("@salary_words@",$salary_words,$print_design);
						}
						
						if($split_array[$replace_val]){
							//Process split informtion 
							$process_function = $split_array[$replace_val];
							if((int)$process_function === 1){
								$transactions_month = $final_result[0]->transactions_month;
								$employee_code      = $final_result[0]->employee_code;
								$loan_info = $this->get_loan_value($transactions_month,$employee_code);
								$print_design = str_replace($replace_val,$loan_info,$print_design);
							}
						}else{
							if($print_block_type === 1){
								$print_design = str_replace($replace_val,$value,$print_design);
								foreach($assign_date_formate_list as $key=>$formate){
									if($column == 'transactions_month'){//transactions month static updated
										$start         = "@".$key."_";
										$end           = "_".$key."@";
										$replace_val   = $start.$column.$end;
										$value         = date('Y-m-d',strtotime("01-".$rslt->$column));
										$date_value    = date_create($value);
										$replace_value = strtoupper(date_format($date_value,$formate));
										$print_design  = str_replace($replace_val,$replace_value,$print_design);
									}else{//not static month updated
										$start         = "@".$key."_";
										$end           = "_".$key."@";
										$replace_val   = $start.$column.$end;
										$replace_val   = $start.$column.$end;
										$date_value    = date_create($value);
										$replace_value = date_format($date_value,$formate);
										$print_design  = str_replace($replace_val,$replace_value,$print_design);
									}
								}
							}else
							if($print_block_type === 2){
								$td_line .= "<td style='text-align:center;'>$value</td>";
							}
							if($count === 1){
								$head_name = ucwords(str_replace("_"," ",$column));
								$th_line .= "<th style='text-align:center;'>$head_name</th>";
							}
						}
					}
					if($print_block_type === 2){
						if($count === 1){
							$th_line  = "$th_line";
						}
						$tr_line .= "<tr>$td_line</tr>";
					}
				}
				if($print_block_type === 2){
					$table_list  = "<table style='width:100%;'><thead>$th_line</thead><tbody>$tr_line</tbody></table>";
					$replce_block = "@".strtolower(str_replace(" ","_",$print_block_name))."@";
					$print_design = str_replace($replce_block,$table_list,$print_design);
				}
			}
			$data['suppressed_data'] = $suppressed_data;
		}
		$data['print_design'] = $print_design;
		return $data;
	}

    #
    //if we changes a shift request then we process a time entry 
	public function time_entry_process($employee_code,$shift_date,$shift_name){
		$time_entry_qry      = 'select COUNT(*) as time_entry_count from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date = "'.$shift_date.'" and cw_time_entry.trans_status = 1';
		$time_entry_info     = $this->runQuery("$time_entry_qry");
		$time_entry_result   =  $this->result($time_entry_info);
		$time_entry_count    = (int)$time_entry_result[0]->time_entry_count;
		if($time_entry_count){
			$time_entry_run_info  = $this->runQuery("'$shift_date','$shift_date','$employee_code'");
            $time_entry_run_rslt  = $this->result_array($time_entry_run_info);
			if($time_entry_run_rslt){
				return true;
			}else{
				return false;
			}
		}else{
			return true;
		}
	}

    # NUMBER TO WORDS CHANGED IN PAYSLIP 
	public function numbertowords($number){
		$prefix = "";
		if($number < 0){
			$prefix = "-";
			$number = ltrim($number,"-");
		}
		$no       = round($number);
		$point    = round($number - $no, 2) * 100;
		$hundred  = null;
		$digits_1 = strlen($no);
		$i = 0;
		$str = array();
		$words = array('0' => '', '1' => 'One', '2' => 'Two',
			'3' => 'Three', '4' => 'Four', '5' => 'Five', '6' => 'Six',
			'7' => 'Seven', '8' => 'Eight', '9' => 'Nine',
			'10' => 'Ten', '11' => 'Eleven', '12' => 'Twelve',
			'13' => 'Thirteen', '14' => 'Fourteen',
			'15' => 'Fifteen', '16' => 'Sixteen', '17' => 'Seventeen',
			'18' => 'Eighteen', '19' =>'Nineteen', '20' => 'Twenty',
			'30' => 'Thirty', '40' => 'Forty', '50' => 'Fifty',
			'60' => 'Sixty', '70' => 'Seventy',
			'80' => 'Eighty', '90' => 'Ninety');
		$digits = array('', 'Hundred', 'Thousand', 'Lakh', 'Crore');
		while ($i < $digits_1) {
			$divider = ($i == 2) ? 10 : 100;
			$number = floor($no % $divider);
			$no = floor($no / $divider);
			$i += ($divider == 10) ? 1 : 2;
			if ($number) {
				$plural = (($counter = count($str ?? [])) && $number > 9) ? '' : null;
				$hundred = ($counter == 1 && $str[0]) ? ' and ' : null;
				$str [] = ($number < 21) ? $words[$number] .
				" " . $digits[$counter] . $plural . " " . $hundred
				:
				$words[floor($number / 10) * 10]
				. " " . $words[$number % 10] . " "
				. $digits[$counter] . $plural . " " . $hundred;
			} else $str[] = null;
		}
		$str = array_reverse($str ?? []);
		$result = implode('', $str ?? []);
		$points = ($point) ? "." . $words[$point / 10]. " ".$words[$point = $point % 10] : '';
		return $prefix.$result;
	}

    # GET LOAN VALUE
    public function get_loan_value($process_month,$employee_code){
		$process_month = explode("-",$process_month ?? "");
		$loan_month    = $process_month[0];
		$loan_year     = $process_month[1];
		$loan_qry = 'select emp_code,install_amount,cw_loan_type.loan_type from cw_loan_installment inner join cw_loan_type on  cw_loan_type.prime_loan_type_id = cw_loan_installment.loan_type where cw_loan_installment.trans_status = 1 and cw_loan_installment.emp_code ="'.$employee_code.'" and cw_loan_installment.install_year ="'.$process_month.'"';
		$loan_data   = $this->runQuery("$loan_qry");
		$loan_result = $this->result($loan_data);
		$loan_tr = "";
		foreach($loan_result as $loan){
			$loan_type      = $loan->loan_type;
			$install_amount = $loan->install_amount;
			$loan_tr .= "<tr>
			<td style='width:77%;'>$loan_type</td>
			<td>$install_amount</td>
			</tr>";
		}
		if($loan_tr !== ""){
			$loan_tr = "<table style='width:100%'>
			$loan_tr
			</table>";
		}
		return $loan_tr;
	}

    # 
    public function send_email_notification($to_email,$first_to_email,$second_to_email,$bcc_mails,$email_subject,$body_content,$email_attachment){
		if($to_email){
			$config_query  = 'SELECT smtp_server,sender_name,bcc,port_no,sender_email,mail_username,mail_password,connection_type FROM cw_mail_configurations WHERE trans_status = 1';
			$config_info   = $this->runQuery("$config_query");
            $config_result = $this->result($config_info);
			$smtp_server   = $config_result[0]->smtp_server;
			$sender_name   = $config_result[0]->sender_name;
			//$bcc           = explode(",",$config_result[0]->bcc);
			$port_no       = $config_result[0]->port_no;
			$sender_email  = $config_result[0]->sender_email;
			$username      = $config_result[0]->mail_username;
			$password      = $config_result[0]->mail_password;
			$conn_type     = $config_result[0]->connection_type;
			try{
				$mail = new PHPMailer();
				//$mail->SMTPDebug = 3; 
				$mail->IsSMTP();
				$mail->Host = $smtp_server; // Your SMTP Parameter
				$mail->Port     = $port_no; // Your Outgoing Port
				$mail->SMTPAuth = true; // This Must Be True
				$mail->Username = $username; // Your Email Address
				$mail->Password = $password; // Your Password
				$mail->SMTPSecure = $conn_type; // Check Your Server's Connections for TLS or SSL
				$mail->From     = $sender_email;
				$mail->FromName = $sender_name;
				if($to_email){
					$mail->AddAddress($to_email);
				}
				if($first_to_email){		
					$mail->AddAddress($first_to_email);
				}
				if($second_to_email){		
					$mail->AddAddress($second_to_email);
				}
				if((int)count($bcc_mails ?? []) > 0){
					foreach ($bcc_mails as $key => $mail_bcc){
						$mail->AddCC($mail_bcc);
					}
				}
				$mail->IsHTML(true);
				$mail->Subject = $email_subject;
				$mail->Body    = $body_content;
				//Attachment
				$folder = $email_attachment;
				if($folder){
					if(file_exists($folder)){
						$mail= $mail->Send();
						if($mail){
							$status = 1;
						}			
					}else{
						$status = 0;
					}
				}else{
					$mail= $mail->Send();
					if($mail){				
						$status = 1;
					}else{
						$status = 0;
					}
				}
			}catch(phpmailerException $e){
				$status = 0;
				$return_values = array('success'=>false,'message'=>"Mail Not Sent");
				return false;
			}catch(Exception $e){
				$status = 0;
				$return_values = array('success'=>false,'message'=>"Mail Not Sent");
				return false;
			}
			if($status){
				
				$return_values = array('success'=>true,'message'=>"Mail Successfully Sent");
				return $return_values;
			}else{
				$return_values = array('success'=>false,'message'=>"Mail Not Sent");
				return false;
			}
		}else{
			$return_values = array('success'=>false,'message'=>"Please Add Employee email id and Try Again!!");
			return $return_values;
		}
	}

    //TIME LOG FUNCTION ONLY FOR MP ENTRY
	public function time_log($post_data,$prime_financial_id,$leave_status,$logged_id){
		// print_r($post_data); die;
		$created_on = date("Y-m-d H:i:s");
		foreach ($post_data as $key => $value) {
			if($key === "employee_code"){
				$employee_code    = $value;
			}
			if($key === "shift_date"){
				$shift_date  = $value;
			}
			if($key === "in_date"){
				$in_date  = $value;
			}
			if($key === "out_date"){
				$out_date    = $value;
			}
			if($key === "in_time"){
				$in_time         = $value;
			}
			if($key === "out_time"){
				$out_time        = $value;
			}
			if($key === "device_code"){
				$device_code     = $value;
			}
		}
		if(!$device_code){	
			return $this->returnResult(FALSE, 'Device Code Should not Empty..!', [], []);
			exit(0);	
		}
		//WE ADD A TIME WITH SECONDS BASED ON IN TIME AND OUT TIME LENGTH
		$in_time_count     = count(explode(":",$in_time ?? "") ?? []);
		$out_time_count    = count(explode(":",$out_time ?? "") ?? []);
		if((int)$in_time_count === 2){
			$in_time       = $in_time.":00";
		}
		if((int)$out_time_count === 2){
			$out_time      = $out_time.":00";
		}
		$from_date_time     = $in_date." ".$in_time;
		$to_date_time       = $out_date." ".$out_time;
		$current_year       = date("Y");
		//IF TIME LOG INSERT ONLY FOR MP APPROVAL 
		if((int)$leave_status === 2){
			//TIME LOG INSERT PROCESS	
			$prime_ins_value    = '("MAN01","'.$from_date_time.'","in","'.$device_code.'","'.$logged_id.'","'.$created_on.'"),("MAN02","'.$to_date_time.'","out","'.$device_code.'","'.$logged_id.'","'.$created_on.'")';

			$in_out_time_ins_qry   = 'INSERT INTO cw_time_log (device_id,log_date,record_type,user_id,trans_created_by,trans_created_date) VALUES '.$prime_ins_value;
            $in_out_time_ins_info  = $this->runQuery("$in_out_time_ins_qry");
			if(!$in_out_time_ins_info){	
				return $this->returnResult(FALSE, 'Time Log Insert Query Error.!', [], []);
				exit(0);	
			}
		}else
		if((int)$leave_status === 4){
			$del_time_log_qry   = 'DELETE FROM cw_time_log WHERE cw_time_log.user_id = "'.$device_code.'" and cw_time_log.device_id in ("MAN01","MAN02") and log_date in ("'.$from_date_time.'","'.$to_date_time.'")';
			if(!$this->runQuery("$del_time_log_qry")){
				return $this->returnResult(FALSE, 'Time Log Delete Query Error.!', [], []);
				exit(0);	
			}
		}
		//TIME ENTRY PROCEDURE CALLING
		$in_out_time_ins_info   = $this->runQuery("CALL itsp_prcatt ('$shift_date','$shift_date','$employee_code')");
		$result                 = $this->result($in_out_time_ins_info);
		mysqli_next_result($this->db);
		if(!$result){
			return $this->returnResult(FALSE, 'Time Entry Procedure Error.!', [], []);
			exit(0);
		}else{
			//TIME ENTRY ACTION STATUS UPDATE
			$action_status     = '';
			if($leave_status === 1){
				$action_status = 2;
			}else
			if($leave_status === 2){
				$action_status = 3; //Approved
			}else
			if($leave_status === 3){
				$action_status = 4;
			}else
			if($leave_status === 4){
				$action_status = 5; //Cancelled
			}
			if($action_status){
				$upd_time_entry = 'UPDATE cw_time_entry SET action_status = "'.$action_status.'",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date = "'.$shift_date.'" and cw_time_entry.trans_status = 1';
				$this->runQuery("$upd_time_entry");
				return array('success' => "true", 'message' => 'proceed');
			}
		}	
	}	

	# FUNCTION FOR EMPLOYEE SHIFT NAME AND PUNCH IN AND OUT TIME GET
	public function empShiftPunchTime($json){
		$employee_code      = $json->code;
		$shift_date         = $json->shift_date;

		$punch_time_qry     = 'select cw_shift_master.shift_name,cw_time_entry.punch_in,cw_time_entry.punch_out from cw_time_entry INNER JOIN cw_shift_master on cw_shift_master.prime_shift_master_id = cw_time_entry.shift_id where cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date = "'.$shift_date.'" and cw_time_entry.trans_status = 1';
		$punch_time_info    = $this->runQuery("$punch_time_qry");
		$punch_time_result  = $this->result($punch_time_info);
		$shift_name         = $punch_time_result[0]->shift_name;
		$punch_in           = $punch_time_result[0]->punch_in;
		$punch_out          = $punch_time_result[0]->punch_out;

		if($punch_in !== NULL && $punch_in !== "0000-00-00 00:00:00"){
			$punch_in       = date("d-m-Y H:i",strtotime($punch_in));
		}else{
			$punch_in       = '';
		}

		if($punch_out !== NULL && $punch_out !== "0000-00-00 00:00:00"){
			$punch_out      = date("d-m-Y H:i",strtotime($punch_out));
		}else{
			$punch_out       = '';
		}
		
		if($punch_in || $punch_out){
			$arr       = array('shift_name' => $shift_name, 'punch_in' => $punch_in, 'punch_out' => $punch_out);
			return $this->returnResult(True, 'Success - proceed', $arr, []);
		}else{
			$shift_arr = array('shift_name' => $shift_name);
			return $this->returnResult(FALSE, 'Punch Data not Available.!', [], []);
		}
	}

	# REQUEST INFO
	public function requestInfo($json){
		$employee_code       = $json->code;
	
		$emp_details_qry      ='SELECT  CONCAT(cw_employees.employee_code,"-",cw_employees.emp_name) AS employee_code,cw_employees.date_of_joining,cw_employees.first_level_approval,cw_employees.second_level_approval,cw_approval_type.approval_type AS approve_type,cw_employees.device_code,cw_department.department AS department FROM cw_employees INNER JOIN cw_department ON cw_department.prime_department_id = cw_employees.department INNER JOIN cw_approval_type ON cw_approval_type.prime_approval_type_id = cw_employees.approve_type WHERE cw_employees.employee_code = "'.$employee_code.'" AND cw_employees.trans_status = 1 GROUP BY cw_employees.employee_code';
		$emp_data             = $this->runQuery($emp_details_qry);
		$emp_result           = $this->result($emp_data);
		$first_level_approval = $emp_result[0]->first_level_approval;
		$hr_approval          = $emp_result[0]->second_level_approval;
		$approval_manager_qry ='SELECT DISTINCT(SELECT CONCAT(employee_code,"-",emp_name) FROM cw_employees WHERE employee_code="'.$first_level_approval.'")AS first_level,(SELECT CONCAT(employee_code,"-",emp_name) FROM cw_employees WHERE employee_code="'.$hr_approval.'")AS hr_approval FROM cw_employees GROUP BY employee_code,prime_employees_id'; 
		$appr_manager_data    = $this->runQuery($approval_manager_qry);
		$approve_manager_rslt = $this->result($appr_manager_data);

		$first_approve        = $approve_manager_rslt[0]->first_level;
		$hr_approval          = $approve_manager_rslt[0]->hr_approval;
		$emp_code             = $emp_result[0]->employee_code;
		if($emp_result[0]->date_of_joining){
			$doj              = date('d-m-Y',strtotime($emp_result[0]->date_of_joining));
		}else{
			$doj              = "-";
		}
		$department           = $emp_result[0]->department;
		$approve_type         = $emp_result[0]->approve_type;
		$request_info_arr     = ['emp_code' => $emp_code, 'doj' => $doj,'department' => $department,'approve_type' => $approve_type,'first_approve' => $first_approve,'hr_approval' => $hr_approval];
		if($request_info_arr){
			return $this->returnResult(True, 'Success - proceed', $request_info_arr, []);
		}else{
			return $this->returnResult(FALSE, 'No Data Available..', [], []);
		}
	}

	# UPLOAD FILES
	public function upload_files($file_path_arr,$send_for,$send_from,$label_id){
		$validate_jwt  = $this->validate_jwt();
		$file_name     = $file_path_arr[0]->doc[0]->fileName;
		$file_data     = base64_decode(($file_path_arr[0]->doc[0]->fileData));	
		$finfo         = new finfo(FILEINFO_MIME_TYPE);	
		$file_type     = $finfo->buffer($file_data); // Get the MIME type from the binary data
		if(($send_for !== "") && ($send_from !== "")){
			if(!file_exists("../upload_files/$send_from")){
				mkdir("../upload_files/$send_from", 0755, true);
				chmod("../upload_files/$send_from", 0755);
			}			
			$file_size        = $file_path_arr[0]->doc[0]->size;
			//MIME Types
			$mime_types       = [ 'jpg'  => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png'  => 'image/png','heif' => 'image/heif','x-heic' => 'image/x-heic', 'x-webp' => 'image/x-webp', 'gif'  => 'image/gif', 'html' => 'text/html', 'pdf'  => 'application/pdf', 'doc'  => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls'  => 'application/vnd.ms-excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'mp3'  => 'audio/mpeg', 'mp4'  => 'video/mp4', 'zip'  => 'application/zip', 'txt'  => 'text/plain','msg'  => 'application/vnd.ms-outlook','eml' => 'message/rfc822'];
			//Get info from Form Settings
			$logged_emp_role  = $validate_jwt->user_right;
			$from_query       = 'select upload_extension,upload_file_size from cw_form_setting  where prime_module_id = "'.$send_from.'" and field_show = "1" and field_type = 10 and label_name = "'.$label_id.'" and trans_status = "1" and FIND_IN_SET("'.$logged_emp_role.'",user_right_for) ORDER BY input_for,field_sort asc';
			$form_data        = $this->runQuery($from_query);
			$form_result      = $this->result($form_data);
			if(count($form_result ?? []) === 0){
				return ['sts' => 'FALSE', 'msg' => 'Invalid Request..'];
				exit(0);
			}
			$upload_filesize  = $form_result[0]->upload_file_size;
			$upload_extension = $form_result[0]->upload_extension;
			$allowed_ext      = explode(",",$upload_extension ?? "");	
			// Find elements in $array1 that match the keys in $array2
			$array_flip       = array_flip($allowed_ext ?? []);
			$allowed_mimes    = array_intersect_key($mime_types ?? [],$array_flip ?? []);
			if (!in_array($file_type, $allowed_mimes ?? [])) {
				return ['sts' => 'FALSE', 'msg' => "Please Upload Valid Mime Type File Such As $upload_extension"];
				exit(0);
			}
			$file_name        = str_replace(" ","_", $file_name);
			$file_size        = $file_size/1000;
			if((int)$upload_filesize === 0){
				$upload_filesize = 500;
			}
			
			if((int)$file_size <= (int)$upload_filesize){
				if($file_name){
					$ext = pathinfo($file_name, PATHINFO_EXTENSION);
					if(in_array($ext, $allowed_ext)){
						$random_digit  = rand(0000,99999999999);
						$new_file_name = "upload_files/$send_from/".$random_digit."_".$file_name;
						$path          = $this->sanitize_input($new_file_name, 10);	
						file_put_contents("../$path", $file_data);	
						return ['sts' => 'TRUE','path' => "$path"];
						exit(0);
					}else{
						return ['sts' => 'FALSE','msg' => "Please upload valid file such as $upload_extension"];
					}
				}else{
					return ['sts' => 'FALSE','msg' => 'Please Upload Valid File or fileName Missing..'];
				}
			}else{
				return ['sts' => 'FALSE','msg' => "File Size Must be below ".$upload_filesize."kb"];
			}
		}else{
			return ['sts' => 'FALSE','msg' => 'Please Refresh Page And Retry..'];
		}
	}

	public function sanitize_input($input, $field_type){
		switch ($field_type){
			case 3 ://INT
			case 11://Mobile Number
				// Sanitize integer values
				return filter_var($input, FILTER_SANITIZE_NUMBER_INT);			
			case 2://Decimal
				// Sanitize float values
				return filter_var($input, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND);	
			case 12://email
				// Sanitize and validate email
				$sanitized_email = filter_var($input, FILTER_SANITIZE_EMAIL);
				return filter_var($sanitized_email, FILTER_VALIDATE_EMAIL) ? $sanitized_email : null;			
			case 10://url
				// Sanitize and validate URL
				$sanitized_url = filter_var($input, FILTER_SANITIZE_URL);
            	return $sanitized_url;
				//return filter_var($sanitized_url, FILTER_VALIDATE_URL) ? $sanitized_url : null;
	
			case 'array'://url
				// Sanitize each element in an array recursively
				if(is_array($input)){
					return array_map(function($item) {
						$sanitized_string = filter_var($item, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
						return htmlspecialchars($sanitized_string, ENT_QUOTES, 'UTF-8');
					}, $input ?? []);
				}
				return null;
	
			case 1://TEXT
			case 4://DATE
			case 5://PICKLIST
			case 6://CHECKBOX
			case 7://MULTIPICK
			case 8://SUMMARY
			case 9://AUTOCOMPLETE
			case 10://FILE UPLOAD
			case 13://DATE & TIME
			case 15://TIME
			default:
				// Sanitize general strings (strips HTML tags, encodes special characters)
				$sanitized_string = filter_var($input, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES);
				return htmlspecialchars($sanitized_string, ENT_QUOTES, 'UTF-8');
		}
	}

	# NEW REQUEST [ms]
	public function addRequest($json){
		$validate_jwt        = $this->validate_jwt(); # JWT TOKEN
		$user_role           = $validate_jwt->user_right;
        $employee_code       = $json->code ?? 0;
        $apidata             = $json->data;
        $form_id             = $json->primeId;
		$request_type        = $apidata->request_type;
		$leave_status        = $apidata->leave_type;
		// API DATA VALIDATION
		$api_validation      =  $this->validations($apidata,'request',$request_type);
		if($api_validation){
			return $this->returnResult(False,'Failed - Validation Error',[],$api_validation);
		}	
		$company_info        = $this->company_info();
		$mp_treat_time_log   = $company_info[0]->mp_treat_as;
		$financial_info      = $this->get_leave_financial_details();
		$prime_financial_id  = $financial_info[0]->prime_leave_financial_year_id;
		$fin_start_date      = $financial_info[0]->starting_date;
		$fin_end_date        = $financial_info[0]->ending_date;
		$post_data           = array();
		$prime_qry_key       = "";
		$prime_qry_value     = "";
		$send_for            = "upload";
		$send_from           = "request";
		$label_id            = "business_file";
		if($apidata){
			foreach($apidata as $key => $data){
				if($key === 'business_file'){
					$file_path_arr     = $data;
					$upd_arr           = $this->upload_files($file_path_arr,$send_for,$send_from,$label_id);
					if($upd_arr['sts'] === 'TRUE'){
						$ins_keys[]                  = "business_file";
						$ins_values[]                = $upd_arr['path'];
						$prime_qry_key              .= $key.",";
						$prime_qry_value            .= '"'.$upd_arr['path'].'",';	
						$post_data['business_file']  = $upd_arr['path'];
					}else{
						return $this->returnResult(False,"Error - , ".$upd_arr['msg'], [], []);
					}
				}else{
					$ins_keys[]        = "$key";
					$ins_values[]      = '"'.$data.'"';
					$prime_qry_key    .= $key.",";
					$prime_qry_value  .= '"'.$data.'",';		
					$post_data[$key]   = $data;
				}
			}
		}

		if((int)$request_type === 1 || (int)$request_type === 3 || (int)$request_type === 8){
			$fromToMonthValidation = $this->fromToMonthValidation($apidata->from_date,$apidata->to_date,"date");
			if($fromToMonthValidation){
				return $this->returnResult(False, 'To Date Must Be Greater Than From Date', [], []);
			}
			$fromToType_validation = $this->fromToType_validation($apidata->from_date,$apidata->to_date,$apidata->from_date_type,$apidata->to_date_type);
			if($fromToType_validation){
				return $this->returnResult(False, $fromToType_validation['msg'], [], []);
			}
		}
		// if((int)$cancellation_request === 1){
		// 	$prime_upd_query   .= 'first_approval_cancel_status="1",second_approval_cancel_status = "1",leave_status = "1",';
		// 	$post_data['first_approval_cancel_status']  = 1; 
		// 	$post_data['second_approval_cancel_status'] = 1;				
		// }
		// //Update query if employee applied cancellation
		$component_query  = 'SELECT pick_table,label_name,components FROM cw_general_setting inner join cw_form_setting on cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 3 and cw_general_setting.trans_status  = 1';
		$component_info   = $this->runQuery($component_query);
		$component_result =  $this->result($component_info);
		$label_name       = $component_result[0]->label_name;

		$common_emp_details_qry    = 'select employee_code,date_of_joining,department,first_level_approval,second_level_approval,approve_type as leave_approve_type,department,'.$label_name.' as component_value,device_code FROM cw_employees WHERE trans_status=1 AND employee_code="'.$employee_code.'"';
		$emp_data_info             = $this->runQuery($common_emp_details_qry);
		$emp_data_result           =  $this->result($emp_data_info);
		
		$first_level_approval      = $emp_data_result[0]->first_level_approval;
		$second_level_approval     = $emp_data_result[0]->second_level_approval;
		if(($first_level_approval === "" || $first_level_approval === "0") && ($second_level_approval === "" || $second_level_approval === "0")){
			return $this->returnResult(FALSE, 'Approver Details Not Mapped in Employee Master.!', [], []);
			exit(0);
		}
		foreach($emp_data_result[0] as $key => $val){
			$post_data[$key]     = $val; 				
			$prime_qry_key      .= $key.",";
			$prime_qry_value    .= '"'.$val.'",';			
		}		
		if((int)$leave_status === 2){
			return $this->returnResult(FALSE, 'Already Your Leave Status Was Approved..!!', [], []);
		}else{
			$created_on = date("Y-m-d H:i:s");
			if((int)$form_id === 0 || !$form_id){
				# FINANCIAl YEAR VALIDATION.

				if($request_type){
					$check_maximum_date        = $this->max_backdate_validation($user_role,$post_data);
					$check_finyear_validation  = $this->check_finyear_validation($post_data,$fin_start_date,$fin_end_date);
					if((int)$check_finyear_validation !== 1){
						exit(0);
					}else 
					if((int)$check_maximum_date !== 1){
						exit(0);
					}	
				}
				if($request_type === "1" || $request_type === "2" || $request_type === "3" || $request_type === "8"){
					$check_leave_validation      = $this->check_leave_validation($post_data);
					if((int)$check_leave_validation !== 1){
						exit(0);
					}
				}else
				if($request_type === "4" || $request_type === "5"){
					$check_permission_validation = $this->check_permission_validation($post_data);
					if((int)$check_permission_validation !== 1){
						echo $check_permission_validation;
						exit(0);
					}
				}else
				if($request_type === "6"){
					$check_shift_change_valid    = $this->shift_change_validation($post_data);
					if((int)$check_shift_change_valid !== 1){
						echo $check_shift_change_valid;
						exit(0);
					}
				}else
				if($request_type === "7"){
					$check_manual_punch_valid    = $this->manual_punch_validation($post_data);
					if((int)$check_manual_punch_valid !== 1){
						echo $check_manual_punch_valid;
						exit(0);
					}
				}	
				if((int)$mp_treat_time_log === 2){						
					$check_common_validation         = $this->common_validation($post_data);
					if((int)$check_common_validation !== 1){
						echo $check_common_validation;
						exit(0);
					}
				}	
				$prime_qry_key     .= "financial_setting_id,trans_created_by,trans_created_date,trans_status";
				$prime_qry_value   .= '"'.$prime_financial_id.'","'.$this->logged_id.'","'.$created_on.'","1"';
				$prime_insert_query = "insert into cw_request ($prime_qry_key) values ($prime_qry_value)";
				$insert_id          = $this->runQuery_insert_id($prime_insert_query);
				if((int)$insert_id){
					if((int)$request_type === 1 || (int)$request_type === 2 || (int)$request_type === 3 || (int)$request_type === 8){
						$this->leave_entry($post_data,$insert_id,$prime_financial_id);
					}else
					if($request_type === "4"){
						$this->permission_entry($post_data,$insert_id,$prime_financial_id);
					}else
					if($request_type === "6"){
						$this->shift_change_entry($post_data,$insert_id,$prime_financial_id);
					}else
					if($request_type === "7"){
						$this->manual_punch_entry($post_data,$insert_id,$prime_financial_id);
					}
				}
				//FUNCTION FOR USING TO MANAGE MODULE EDIT VIEW AND CANCEL BUTTON VALIDATION ARRAY GET
				$result            = $this->request_data_arr($prime_financial_id);
				$leave_status_arr  = $result['leave_status_arr'];
				$leave_cancel_arr  = $result['leave_cancel_arr'];
				$emp_cancel_arr    = $result['emp_cancel_arr'];

				return $this->returnResult(TRUE, 'Request Successfully Added..', [], []);
			}else{
				return $this->returnResult(FALSE, 'Please Try After Sometime..!', [], []);
			}
		}
	}
	public function approvedCancel($json){
		$validate_jwt          = $this->validate_jwt();
		$logged_id             = $validate_jwt->code;
		$created_on            = date("Y-m-d H:i:s");
		$form_id               = $json->prime_id;
		$cancellation_reason   = $json->cancel_reason;
		// GET REQUEST DATA BY FORM ID
		$req_data_qry 		   = 'SELECT leave_approve_type,employee_code,request_date,from_date,to_date,shift_date,permission_date,request_type FROM cw_request WHERE prime_request_id = "'.$form_id.'"';
		$req_data_info         = $this->runQuery("$req_data_qry");
		$req_data_rslt         = $this->result_array($req_data_info);
		if($req_data_rslt){
			$post_data         = array();
			foreach($req_data_rslt as $key => $data){
				$post_data[$key]   = $data;
			}
			$employee_code     = $post_data[0]['employee_code'];
			$request_date	   = $post_data[0]['request_date'];
		}else{
			return $this->returnResult(FALSE, 'Invalid Request..!', [], []);
		}
		$ot_check_qry          = 'select sum(over_time) as over_time from cw_overtime_entry where employee_code="'.$employee_code.'" and entry_date = "'.$request_date.'"';
		$over_time_info        = $this->runQuery("$ot_check_qry");
		$over_time_rslt        = $this->result_array($over_time_info);
		$over_time             = $over_time_rslt[0]['over_time'];
		if($over_time > 0){
			return $this->returnResult(FALSE, 'Overtime Already Exist in this Date Please Cancel...!', [], []);
		}
		$this->cancel_entry($post_data[0],$form_id,$cancellation_reason,$logged_id);
		$prime_upd_query    = '';
		$prime_upd_query   .= 'cancellation_request = 1,first_approval_cancel_status="1",second_approval_cancel_status = "1",leave_status = "1",cancellation_reason = "'. $cancellation_reason .'",';
		$prime_upd_query   .= 'trans_updated_by = "'. $logged_id .'",trans_updated_date = "'.$created_on.'"';
		$prime_update_query = 'UPDATE cw_request SET '. $prime_upd_query .' WHERE prime_request_id = "'. $form_id .'"';
		$this->runQuery("$prime_update_query");
		return $this->returnResult(TRUE, 'Successfully updated', [], []);
	}
	public function cancel_entry($post_data,$form_id,$cancellation_reason,$logged_id){
		$created_on            = date("Y-m-d H:i:s");    
		foreach ($post_data as $key => $value) {
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "request_date"){
				$key = "applied_on";
			}
			if($key === "from_date"){
				$from_date =  date('Y-m-d',strtotime($value));
			}
			if($key === "to_date"){
				$to_date =  date('Y-m-d',strtotime($value));
			}
			if($key === "shift_date"){
				$shift_date =  date('Y-m-d',strtotime($value));
			}
			if($key === "permission_date"){
				$permission_date =  date('Y-m-d',strtotime($value));
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_approve_type"){
				$leave_approve_type = $value;
			}
		}

		//TIME OF SETTING BASED SALARY START AND END DATE DETAILS
		$month_day_info     = $this->tos_day_info($employee_code,"3"); // 3 => Leave Entry
		if(count($month_day_info) ?? []){
			$salary_start_date  = date("Y-m-d",strtotime($month_day_info["salary_start_date"]));
			// $salary_end_date    = date("Y-m-d",strtotime($month_day_info["salary_end_date"]));
			$salary_end_date    = date("Y-m-d",strtotime($month_day_info["year_end_date"]));

			$check_sts          = false;
			if($request_type === "1" || $request_type === "2" || $request_type === "3" || $request_type === "8"){ 
				if($from_date >= $salary_start_date && $to_date <= $salary_end_date){
					$check_sts  = true;
				}
			}else
			if($request_type === "4" || $request_type === "5"){
				if($permission_date >= $salary_start_date){
					$check_sts  = true;
				}
			}else
			if($request_type === "6"){
				if($shift_date >= $salary_start_date){
					$check_sts  = true;
				}
			}else
			if($request_type === "7"){
				if($shift_date >= $salary_start_date){
					$check_sts  = true;
				}
			}
			if($check_sts){
				$upd_approval_qry           = 'UPDATE cw_approval SET cancellation_request = "1",cancellation_reason = "'. $cancellation_reason .'",leave_status = "1",first_approval_cancel_status = "1",second_approval_cancel_status = "1",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE prime_request_id = "'.$form_id.'" and cw_approval.trans_status = 1';
				$this->runQuery("$upd_approval_qry");

				$employee_detail_qry  		= 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
				$employee_detail_info  		= $this->runQuery("$employee_detail_qry");
				$employee_detail_result  	= $this->result($employee_detail_info);
				$view_id 					= $employee_detail_result[0]->prime_employees_id;
				$first_level_approval_code	= $employee_detail_result[0]->first_level_approval;
				$second_level_approval_code	= $employee_detail_result[0]->second_level_approval;
				$first_approval_qry  	    = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
				$first_approval_info  	    = $this->runQuery("$first_approval_qry");
				$first_approval_result      = $this->result($first_approval_info);
				$first_approval_mail 	    = $first_approval_result[0]->company_email_id;

				$second_approval_qry  	    = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
				$second_approval_info  	    = $this->runQuery("$second_approval_qry");
				$second_approval_result     = $this->result($second_approval_info);
				$second_approval_mail 	    = $second_approval_result[0]->company_email_id;
				$print_type_id              = "";
				if($request_type === "1" || $request_type === "2"){ 
					$print_type_id = 24;
				}else
				if($request_type === "3" || $request_type === "8"){ 
					$print_type_id = 36;
				}else
				if($request_type === "4" || $request_type === "5"){
					$print_type_id = 30;
				}else
				if($request_type === "6"){
					$print_type_id = 42;
				}else
				if($request_type === "7"){
					$print_type_id = 48;
				}
				if((int)$leave_approve_type === 1){
					return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
				}else
				if((int)$leave_approve_type === 2){
					return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
				}else
				if((int)$leave_approve_type === 3){
					return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
				}else
				if((int)$leave_approve_type === 4){
					return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
				}
				return true;
			}else{
				echo  $this->returnResult(FALSE, 'Could not Cancel.. Because Payroll Already Processed for this Month...!', [], []);	
				exit(0);
			}
		}else{
			echo  $this->returnResult(FALSE, 'Please Set Month Day for this Category...', [], []);
			exit(0);
		}
	}
	# UNDER CONSTRUCTION [MS]
	public function check_finyear_validation($post_data, $fin_start_date, $fin_end_date){
		$fin_start_date_dmy = date("d-m-Y", strtotime($fin_start_date));
    	$fin_end_date_dmy   = date("d-m-Y", strtotime($fin_end_date));
	    $dates_to_check     = array("shift_date" => "Shift date","permission_date" => "Permission date","from_date" => "From date","to_date" => "To date");
	    foreach($dates_to_check as $date_key => $date_label){
	        $date = $post_data[$date_key];
			if($date){
				if($date !== '1970-01-01'){
					if(!($date >= $fin_start_date && $date <= $fin_end_date)){
						echo $this->returnResult(FALSE, "$date_label should be in this financial year [ $fin_start_date_dmy To $fin_end_date_dmy ]", [], []);
						exit(0);
					}else{
						return true;
					}
				}
			}else{
				return true;
			}
	    }
	}

	public function check_perday_validation($post_data,$request_type){
		$component_value = $post_data["component_value"];
		$employee_code   = $post_data["employee_code"];
		$shift_date 	 = $post_data["shift_date"];
		$permission_date = $post_data["permission_date"];
		$from_date  	 = $post_data["from_date"];
		$to_date      	 = $post_data["to_date"];					
		$sd_qry          = "";
		$pd_qry          = "";
		$od_qry          = "";
		$lv_qry          = "";
		//MANUAL,SHIFT.
		if($request_type === "6" || $request_type === "7"){
			$sd_qry      = 'AND shift_date = "'.$shift_date.'"';	
			$pd_qry      = 'AND permission_date = "'.$shift_date.'"';	
			$lv_qry      = 'AND leave_date >= "'.$shift_date.'" AND leave_date <= "'.$shift_date.'"';	
			$od_qry      = 'AND on_duty_date >= "'.$shift_date.'" AND on_duty_date <= "'.$shift_date.'"';		
		}else
		//PERMISSION.
		if($request_type === "4"){			
			$sd_qry      = 'AND shift_date = "'.$permission_date.'"';	
			$pd_qry      = 'AND permission_date = "'.$permission_date.'"';
			$lv_qry      = 'AND leave_date >= "'.$permission_date.'" AND leave_date <= "'.$permission_date.'"';	
			$od_qry      = 'AND on_duty_date >= "'.$permission_date.'" AND on_duty_date <= "'.$permission_date.'"';
		}else
		//LEAVE,ONDUTY,BUSINESS TRIP.
		if($request_type === "1" || $request_type === "3" || $request_type === "8"){			
			$sd_qry      = 'AND shift_date >= "'.$from_date.'" AND shift_date <= "'.$to_date.'"';
			$pd_qry      = 'AND permission_date >= "'.$from_date.'" AND permission_date <= "'.$to_date.'"';
			$lv_qry      = 'AND leave_date >= "'.$from_date.'" AND leave_date <= "'.$to_date.'"';	
			$od_qry      = 'AND on_duty_date >= "'.$from_date.'" AND on_duty_date <= "'.$to_date.'"';
		}
		$shift_qry       = 'SELECT count(employee_code) AS count FROM cw_request WHERE employee_code= "'.$employee_code.'"  '.$sd_qry.' AND leave_status IN (1,2) AND trans_status = 1';
		$shift_info      = $this->runQuery($shift_qry);
		$shift_rslt      =  $this->result($shift_info);

		$permission_qry  = 'SELECT count(employee_code) AS count FROM cw_request WHERE employee_code= "'.$employee_code.'" '.$pd_qry.' AND leave_status IN (1,2) AND trans_status = 1';
		$permission_info = $this->runQuery($permission_qry);
		$permission_rslt =  $this->result($permission_info);

		$on_duty_qry     = 'SELECT count(employee_code) AS count FROM cw_on_duty_entry WHERE employee_code = "'.$employee_code.'" '.$od_qry.' AND on_duty_status IN (1,2) AND trans_status = 1';
		$on_duty_info    = $this->runQuery($on_duty_qry);
		$on_duty_rslt    =  $this->result($on_duty_info);

		$leave_qry       = 'SELECT count(employee_code) AS count FROM cw_leave_entry WHERE employee_code = "'.$employee_code.'" '.$lv_qry.' AND leave_status IN (1,2) AND trans_status = 1';
		$leave_info      = $this->runQuery($leave_qry);
		$leave_rslt      =  $this->result($leave_info);
		//FINAL VALIDATION.
		if((int)$shift_rslt[0]->count > 0 || (int)$permission_rslt[0]->count > 0 || (int)$on_duty_rslt[0]->count > 0 || (int)$leave_rslt[0]->count > 0){
			echo $this->returnResult(FALSE, 'Exceeded limit - One Request per day.', [], []);
			exit(0);
		}else{
			return true;
		}
	}

	public function check_leave_validation($post_data){	
		$component_value       = $post_data["component_value"];
		$request_type          = (int)$post_data["request_type"];
		$employee_code         = $post_data["employee_code"];
		$leave_type            = $post_data["leave_type"];
		$leave_balance         = $post_data["leave_balance"];
		$from_date 	           = $post_data["from_date"];
		$from_date_type        = (int)$post_data["from_date_type"];
		$to_date 	           = $post_data["to_date"];
		$to_date_type          = (int)$post_data["to_date_type"];  
		$no_of_days            = $post_data["no_of_days"];
		$leave_financial_info  = $this->get_leave_financial_details();
		$prime_financial_id    = $leave_financial_info[0]->prime_leave_financial_year_id;
		$salary_start_date     = "";
		$salary_end_date       = "";
		$year_end_date         = "";
		//TIME OF SETTING BASED SALARY START AND END DATE DETAILS
		$month_day_info        = $this->tos_day_info($employee_code,"3"); // 3 => Leave Entry
		$salary_start_date     = date("Y-m-d",strtotime($month_day_info["salary_start_date"]));
		$salary_end_date       = date("Y-m-d",strtotime($month_day_info["salary_end_date"]));
		$year_end_date         = date("Y-m-d",strtotime($month_day_info["year_end_date"]));
		//for Get Leave Creation
		$leave_creation_qry    = 'SELECT coff,coff_late,is_el,leave_description from cw_leave_creation where cw_leave_creation.trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
		$leave_creation_info   = $this->runQuery($leave_creation_qry);
		$leave_creation_result = $this->result($leave_creation_info);
		$coff 	               = $leave_creation_result[0]->coff;
		$coff_late 	           = $leave_creation_result[0]->coff_late;
		$is_el 	               = $leave_creation_result[0]->is_el;
		$leave_description     = $leave_creation_result[0]->leave_description;
		if($request_type === 1){ // check for Leave
			if((int)$coff_late === 1){ // For Coff Late created for Rebar
				if(($from_date === $to_date) && (int)$from_date_type === 2 && (int)$to_date_type === 2){
					$this->check_coff_late($employee_code,$from_date);
				}else{
					echo $this->returnResult(FALSE, 'Coff Late will be available for the Next Day first Half only.!', [], []);
					exit(0);
				}				
			}
			if((int)$coff === 1){ // Check Coff Balance Exist or not
				$coff_count = $this->check_coff_exist($employee_code,$prime_financial_id,$from_date);
				if($coff_count < $no_of_days){
					echo $this->returnResult(FALSE, 'Compensatory Leave Date should be greater than Comp off Credited date.!', [], []);
					exit(0);
				}
			}
			// IS EL SHOULD NOT ALLOW FULLDAY
			if((int)$is_el === 1 && ((int)$from_date_type !== 1 || (int)$to_date_type !== 1)) {
				echo $this->returnResult(FALSE, "This leave type $leave_description is only accept full day Leave", [], []);
				exit(0);
			}
		}
		if($salary_start_date <= $from_date && $year_end_date >= $to_date){
			//SHIFT DATE AVAILABILITY TO CHECK FOR LEAVE DATES
			/*$shift_date_validate      = $this->shift_date_validate($employee_code,$from_date,$to_date);
			if($shift_date_validate){*/
			//PERMISISON REQUEST VALIDATE
			$other_req_validate   = $this->other_request_exist($employee_code,$prime_financial_id,$from_date,$to_date,$from_date_type,$to_date_type);
			if($other_req_validate){
				return true;
			}
			//}
		}else{
			echo $this->returnResult(FALSE, 'Please Check a Salary Start Date and End Date..!', [], []);
		}		
	}

    //CHECK A PERMISSION IN BEFORE SUBMIT
    public function check_permission_validation($post_data){
        $component_value     = $post_data["component_value"];
        $employee_code       = $post_data["employee_code"];
        $permission_date     = $post_data["permission_date"];
        $shift_name 	     = $post_data["shift_name"];
        $permission_type     = $post_data["permission_type"];
        $in_time             = $post_data["in_time"];
        $out_time            = $post_data["out_time"];
        $total_time          = $post_data["total_time"];
		$device_code         = $post_data["device_code"];
		$financial_info      = $this->get_leave_financial_details();
		$prime_financial_id  = $financial_info[0]->prime_leave_financial_year_id;

		// VALIDATION FOR PERMISSION ONDUTY TYPE 
		if($permission_type == "3"){
			$half_work_hour_qry  = 'SELECT half_work_hour FROM cw_shift_master WHERE prime_shift_master_id = "'.$shift_name.'"';
			$half_work_hour_info = $this->runQuery($half_work_hour_qry);
			$half_work_hour_rslt = $this->result($half_work_hour_info);
			$half_work_hour      = $half_work_hour_rslt[0]->half_work_hour;
			if($total_time > $half_work_hour){
				echo $this->returnResult(FALSE, 'More Than Half Day Hours Should Request Onduty Instead Of Permission...', [], []);
				exit(0);
			}
		}

        //function for check a pending Shift Change Request request status
        $check_exist_shift_sts  = $this->check_exist_shift_sts($component_value,$employee_code,$permission_date);
        if($check_exist_shift_sts){
			//Check DATE Exist from LEAVE AND OD Entry (only for FULL DAY TYPE)
			$check_exist_leave_od  = $this->check_exist_leave_od($component_value,$prime_financial_id,$employee_code,$permission_date);
			if(!$check_exist_leave_od){
				echo $this->returnResult(FALSE, 'Already Transaction Exist.! Please Cancel the Previous Transaction and try Again.!', [], []);
           		exit(0);
			}else{
				if($in_time === "00:00" || $in_time === ""){
					echo $this->returnResult(FALSE, 'Intime should not be Empty!', [], []);
					exit(0);
				}else
				if($out_time === "00:00" || $out_time === ""){
					echo $this->returnResult(FALSE, 'Outtime Should not be Empty!', [], []);
					exit(0);
				}else
				if(strtotime($in_time) >= strtotime($out_time)){
					echo $this->returnResult(FALSE,'Out Time Must Be Greater Than In Time..',[], []);
				}else
				if($in_time && $out_time && $shift_name){
					//FUNCTION FOR GET A SHIFT IN AND OUT TIME DR CODE
					$shift_master_rslt  = $this->shift_time_qry($shift_name);
					$from_time          = date("H:i",strtotime($shift_master_rslt[0]->from_time));
					$to_time            = date("H:i",strtotime($shift_master_rslt[0]->to_time));
					/*if($from_time && $to_time){
						if(($from_time !== $in_time) && ($to_time !== $out_time)){
							echo json_encode(array('success' => false, 'message' => 'Permission Only Allow Shift Start or Shift End Time..'));
						}else{*/
							if((int)$permission_type === 4){
								$coff_permission_date   = date("Y-m-d",strtotime("-1 days",strtotime($permission_date)));
								//FUNCTION FOR GET TIME ENTRY COFF HOURS
								$coff_hrs_rslt          = $this->time_entry_coff_hrs($prime_financial_id,$employee_code,$coff_permission_date);
								$coff_hrs               = $coff_hrs_rslt[0]["coff_hours"];
								if(!$coff_hrs || $coff_hrs === "0"){
									echo $this->returnResult(FALSE, 'Coff Hours not Available Please Check Time Entry.!', [], []);	
									exit(0);
								}else{
									//TIME ENTRY COFF HOURS BASED TOTAL HOURS VALIDATIONS CHECK
									$total_time_arr   = explode(":",$total_time ?? "");
									$total_hrs        = $total_time_arr[0]*60 + $total_time_arr[1];
									// echo $total_hrs;die;
									if($total_hrs > $coff_hrs){
										echo $this->returnResult(FALSE, 'Total Permission Hours should not Greater than Coff Hours.!', [], []);
										exit(0);	
									}else{
										$in_time_count       = count(explode(":",$in_time ?? "") ?? []);
										$out_time_count      = count(explode(":",$out_time ?? "") ?? []);
										if((int)$in_time_count === 2){
											$in_time         = $in_time.":00";
										}
										if((int)$out_time_count === 2){
											$out_time        = $out_time.":00";
										}
										$in_date_time        = date("Y-m-d H:i:s",strtotime($permission_date." ".$in_time));
										$out_date_time       = date("Y-m-d H:i:s",strtotime($permission_date." ".$out_time));
										
										//TIME LOG MIN IN TIME GET
										//--- DON'T DELETE ----
										// $log_in_time_rslt    = $this->time_log_in_time($prime_financial_id,$employee_code,$permission_date,$device_code);
										$log_in_time_qry     = 'select punch_in as min_log_date,punch_out as max_log_date from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and att_date = "'.$permission_date.'" and cw_time_entry.trans_status = 1';
										$log_in_time_info    = $this->runQuery($log_in_time_qry);
										$log_in_time_rslt    = $this->result_array($log_in_time_info);

										$min_log_date_time   = "";
										if($log_in_time_rslt[0]["min_log_date"] !== "0000-00-00 00:00:00"){
											$min_log_date_time     = date('Y-m-d H:i:s', strtotime($log_in_time_rslt[0]["min_log_date"]));
										}
										//echo "BSK $out_date_time :: $min_log_date_time"; die;	
										//TIME LOG MIN IN TIME BASED VALIDATION
										if($min_log_date_time){
											if($in_date_time >= $min_log_date_time){
												echo $this->returnResult(FALSE, "In Date and Time should Lesser than or equal to Punch in Time ($min_log_date_time).!", [], []);
												exit(0);	
											}else
											if($out_date_time >= $min_log_date_time){
												echo $this->returnResult(FALSE, "Out Date and Time should Lesser than or equal to Punch in Time ($min_log_date_time).!", [], []);
												exit(0);
											}
										}
									} 
								}
							}
							//permission validation exist check
							return $this->permission_setting_check($employee_code,$permission_date,$shift_name,$in_time,$out_time,$total_time,$permission_type);
					/* }
					}else{
						echo json_encode(array('success' => false, 'message' => 'Shift Time not Added to Shift Master.!'));				
					}*/		
				}
			}
        }else{
			echo $this->returnResult(FALSE, 'Already Transaction Exist with the current Shift.! Please Cancel the Previous Transaction and try Again.!', [], []);
            exit(0);
        }
    }

	//CHECK A MANUAL PUCH IN BEFORE SUBMIT
	public function shift_change_validation($post_data){
		$component_value          = $post_data["component_value"];
		$employee_code            = $post_data["employee_code"];
		$shift_date 	          = date("Y-m-d",strtotime($post_data["shift_date"]));
        $current_shift            = (int)$post_data["current_shift"];
        $change_shift             = (int)$post_data["change_shift"];

        //function for check a pending request status
        $check_exist_request_sts  = $this->check_exist_request_sts($component_value,$employee_code,$shift_date);
        if($check_exist_request_sts){
        	if($shift_date && $current_shift && $change_shift){
	        	if($current_shift === $change_shift){
					echo $this->returnResult(FALSE, "Don't Choose Same Shift Name.? Please Check it.!", [], []);
					exit(0);
	       		}else{
	       			return true;
	       		}
	        }
        }else{
			echo $this->returnResult(FALSE, 'Already Transaction Exist with the current Shift.. Please Cancel the Previous Transaction and try Again.!', [], []);
			exit(0);
        }
    }

	//CHECK A MANUAL PUCH IN BEFORE SUBMIT
	public function manual_punch_validation($post_data){
		$component_value     = $post_data["component_value"];
		$employee_code       = $post_data["employee_code"];
		$shift_date 	     = date("Y-m-d",strtotime($post_data["shift_date"]));
		$in_date 	         = date("Y-m-d",strtotime($post_data["in_date"]));
		$in_time             = $post_data["in_time"];
		$out_date 	         = date("Y-m-d",strtotime($post_data["out_date"]));
		$out_time            = $post_data["out_time"];
		$total_time          = $post_data["total_time"];
		$day_type            = (int)$post_data["day_type"];
		$mp_reason           = (int)$post_data["mp_reason"];
		$device_code         = $post_data["device_code"];
		$in_date_time        = date('Y-m-d H:i', strtotime($in_date.' '.$in_time));
		$out_date_time       = date('Y-m-d H:i', strtotime($out_date.' '.$out_time));
		$company_info        = $this->company_info();
		$mp_treat_time_log   = $company_info[0]->mp_treat_as;
		
		//function for check a pending request status
        $check_exist_shift_sts  = $this->check_exist_shift_sts($component_value,$employee_code,$shift_date);
        if($check_exist_shift_sts){
			if($in_time === "00:00" || $in_time === ""){
				echo $this->returnResult(FALSE, 'In Time should not be Empty!', [], []);
				exit(0);
			}else
			if($out_time === "00:00" || $out_time === ""){
				echo $this->returnResult(FALSE, 'Out Time Should not be Empty!', [], []);
				exit(0);
			}else
			if($total_time === "00:00" || $total_time === ""){
				echo $this->returnResult(FALSE, 'total Time Should not be Empty!', [], []);
				exit(0);
			}else{
				$next_date       = date('Y-m-d', strtotime('+1 day', strtotime($shift_date)));
				$prev_date       = date('Y-m-d', strtotime('-1 day', strtotime($shift_date)));				
				//THIS CHOOSE DATE USED FOR CHECK OUR OUT DATE IS TOMORROW OR NOT
				$choose_date     = date('Y-m-d', strtotime('+1 day', strtotime($in_date)));
				//FOR WE ONCE CHANGE A IN TIME OR OUT TIME NOT SECONDS ADDED SO STATICALLY ADD 
				$in_time_count   = count(explode(":",$in_time ?? "") ?? []);
				$out_time_count  = count(explode(":",$out_time ?? "") ?? []);
				if((int)$in_time_count === 2){
					$in_time     = $in_time.":00";
				}
				if((int)$out_time_count === 2){
					$out_time    = $out_time.":00";
				}
				if($in_date === $out_date){
					if($in_time >= $out_time){
						echo $this->returnResult(FALSE, 'Out Time should be Greater than In Time..!', [], []);
						exit(0);
					}	
				}else
				if($in_date !== $out_date){
					if($in_date_time >= $out_date_time){
						echo $this->returnResult(FALSE, 'Out Date and Time should be Greater than In Date Time..!', [], []);
						exit(0);
					}
				}
				//check exist conditions from manual punch entry table
				$man_punch_check_qry   = 'SELECT COUNT(*) as count from cw_manual_punch_entry where employee_code = "'.$employee_code.'" and cw_manual_punch_entry.shift_date = "'.$shift_date.'" and leave_status in (1,2) and trans_status = 1';
				// and (day_type = "'.$day_type.'" or day_type = 1)
				$man_punch_check_info  = $this->runQuery($man_punch_check_qry);
				$man_punch_check_rslt  =  $this->result($man_punch_check_info);
				$mp_check_count        = (int)$man_punch_check_rslt[0]->count;
				if($mp_check_count){
					echo $this->returnResult(FALSE, 'Manual Punch Request Already Exist in the Same Date..!', [], []);
					exit(0);
				}else{
					//this condition check only for forgot punch reason only
					// if($this->config->item("db_name") === 'tcl_hrms' || $this->config->item("db_name") === 'tcl_dev'){
					// 	if($mp_reason === 2){
					// 		$process_month         = date("m-Y",strtotime($in_date));
					// 		//DR CODE SALARY START DATE AND END DATE DETAILS GET
					// 		$salary_start_end_info = $this->tos_sal_strt_end_info("3",$process_month); // 3 => Leave Entry
					// 		if(count($salary_start_end_info)){
					// 			$salary_start_date     = date("Y-m-d",strtotime($salary_start_end_info['salary_start_date']));
					// 			$salary_end_date       = date("Y-m-d",strtotime($salary_start_end_info['salary_end_date']));
					// 			$man_punch_check_qry   = 'SELECT COUNT(*) as count from cw_manual_punch_entry where employee_code = "'.$employee_code.'" and cw_manual_punch_entry.shift_date between "'.$salary_start_date.'" and "'.$salary_end_date.'" and leave_status in (1,2) and mp_reason = 2 and trans_status = 1';
					// 			$man_punch_check_info  = $this->runQuery($man_punch_check_qry);
					// 			$man_punch_check_rslt  =  $this->result($man_punch_check_info);
					// 			$mp_check_count        = (int)$man_punch_check_rslt[0]->count;
					// 			if($mp_check_count >= 3){
					// 				echo $this->returnResult(FALSE, 'You Have Reached a Maximum Forgot Punch Request..Please Contact Admin..?', [], []);
					// 				exit(0);
					// 			}
					// 		}
					// 	}
					// }
				}
				//TIME LOG BASED MANUAL PUNCH
				if((int)$mp_treat_time_log === 1){
					// if($this->config->item("db_name") !== 'rebar_hrms_db'){ //If multi inout
						//TIME LOG MIN AND MAX DATE AND TIME GET
						// GROUP BY cw_time_log.user_id,date_format(str_to_date(cw_time_log.log_date, "%Y-%m-%d %H:%i:%s"),"%Y-%m-%d")
						$time_log_date_qry    = 'select punch_in as min_log_date,punch_out as max_log_date from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and att_date = "'.$in_date.'" and cw_time_entry.trans_status = 1';
						$time_log_date_info  = $this->runQuery($time_log_date_qry);
						$time_log_date_rslt  = $this->result_array($time_log_date_info);
						if(empty($time_log_date_rslt)){
							return true;
						}else{
							$min_log_date_time = "";
							$max_log_date_time = "";
							if($time_log_date_rslt[0]["min_log_date"] && $time_log_date_rslt[0]["min_log_date"] !== "0000-00-00 00:00:00" && $time_log_date_rslt[0]["min_log_date"] !== "1970-01-01 05:30:00" && $time_log_date_rslt[0]["min_log_date"] !== NULL){
								$min_log_date_time     = date('Y-m-d H:i', strtotime($time_log_date_rslt[0]["min_log_date"]));
							}

							if($time_log_date_rslt[0]["max_log_date"] && $time_log_date_rslt[0]["max_log_date"] !== "0000-00-00 00:00:00" && $time_log_date_rslt[0]["max_log_date"] !== "1970-01-01 05:30:00" && $time_log_date_rslt[0]["max_log_date"] !== NULL){
								$max_log_date_time     = date('Y-m-d H:i', strtotime($time_log_date_rslt[0]["max_log_date"]));
							}
							//TIME LOG IN AND OUT TIME BASED VALIDATIONS						
							if($min_log_date_time){
								if($in_date_time > $min_log_date_time){
									echo $this->returnResult(FALSE, 'In Time should be Lesser than Punch In Time..!', [], []);
									exit(0);
								}
							}
							if($max_log_date_time){
								if($out_date_time < $max_log_date_time){
									echo $this->returnResult(FALSE, 'Out Time should be Greater than Punch Out Time..!', [], []);
									exit(0);
								}	
							}
							return true;
						}
					// }else{
					// 	return true;
					// }
				}else{
					$shift_time_qry    = 'select cw_shift_import.shift_name,cw_shift_import.shift_date as shift_date,cw_shift_master.from_time,cw_shift_master.to_time,cw_shift_master.first_half as first_half,cw_shift_master.second_half as second_half,cw_shift_master.shift_status,cw_shift_master.shift_start,cw_shift_master.shift_end,cw_shift_master.in_time as import_in_time,cw_shift_master.out_time as import_out_time,cw_shift_master.half_work_hour,cw_shift_master.full_work_hour from cw_shift_import inner join cw_shift_master on cw_shift_master.prime_shift_master_id = cw_shift_import.shift_name where cw_shift_import.employee_code = "'.$employee_code.'" and cw_shift_import.shift_date = "'.$shift_date.'" and cw_shift_import.trans_status = 1';
					$shift_time_info   = $this->runQuery($shift_time_qry);
					$shift_time_result =  $this->result($shift_time_info);
					$shift_date        = $shift_time_result[0]->shift_date;
					$today_shift_next  = date('Y-m-d', strtotime('+1 day', strtotime($shift_date)));
					$from_time         = $shift_time_result[0]->from_time;
					$to_time           = $shift_time_result[0]->to_time;
					$first_half        = $shift_time_result[0]->first_half;
					$second_half       = $shift_time_result[0]->second_half;
					$shift_status      = (int)$shift_time_result[0]->shift_status;
					$shift_start       = (int)$shift_time_result[0]->shift_start;
					$shift_end         = (int)$shift_time_result[0]->shift_end;
					$import_in_time    = $shift_time_result[0]->import_in_time;
					$import_out_time   = $shift_time_result[0]->import_out_time;
					$half_work_hour    = date('H:i:s', strtotime($shift_time_result[0]->half_work_hour));
					$full_work_hour    = date('H:i:s', strtotime($shift_time_result[0]->full_work_hour));
					$total_time        = date('H:i:s', strtotime($total_time));
					$shift_from_date   = date('Y-m-d H:i:s', strtotime($shift_date.' '.$from_time));
					$shift_to_date     = date('Y-m-d H:i:s', strtotime($shift_date.' '.$to_time));
					$shift_first_half  = date('Y-m-d H:i:s', strtotime($shift_date.' '.$first_half));
					$shift_second_half = date('Y-m-d H:i:s', strtotime($shift_date.' '.$second_half));
					$import_in_date    = date('Y-m-d H:i:s', strtotime($shift_date.' '.$import_in_time));
					$import_out_date   = date('Y-m-d H:i:s', strtotime($shift_date.' '.$import_out_time));
					$in_date_time      = date('Y-m-d H:i:s', strtotime($in_date.' '.$in_time));
					$out_date_time     = date('Y-m-d H:i:s', strtotime($out_date.' '.$out_time));

					if($shift_status === 1){
						if($shift_start === 3){
							$import_in_date   = date('Y-m-d H:i:s', strtotime($prev_date.' '.$import_in_time));
						}	
						if($shift_end === 2){
							$import_out_date  = date('Y-m-d H:i:s', strtotime($next_date.' '.$import_out_time));
						}	
					}else
					if($shift_status === 2){
						$shift_to_date         = date('Y-m-d H:i:s', strtotime($next_date.' '.$to_time));
						if($from_time > $first_half){
							$shift_first_half  = date('Y-m-d H:i:s', strtotime($next_date.' '.$first_half));
							$shift_second_half = date('Y-m-d H:i:s', strtotime($next_date.' '.$second_half));
						}
						if($shift_end === 2){
							$import_out_date   = date('Y-m-d H:i:s', strtotime($next_date.' '.$import_out_time));
						}	
					}else
					if($shift_status === 3){
						$shift_from_date       = date('Y-m-d H:i:s', strtotime($next_date.' '.$from_time));
						$shift_to_date         = date('Y-m-d H:i:s', strtotime($next_date.' '.$to_time));
						$shift_first_half      = date('Y-m-d H:i:s', strtotime($next_date.' '.$first_half));
						$shift_second_half     = date('Y-m-d H:i:s', strtotime($next_date.' '.$second_half));
						if($shift_start === 1){
							$import_in_date    = date('Y-m-d H:i:s', strtotime($shift_date.' '.$import_in_time));
						}	
						if($shift_end === 2){
							$import_out_date   = date('Y-m-d H:i:s', strtotime($next_date.' '.$import_out_time));
						}	
					}

					if($day_type === 1){
						if($shift_first_half <= $in_date_time || $import_in_date > $in_date_time){
							echo $this->returnResult(FALSE, 'Please Map Correct In Date or In Time..!!', [], []);
							exit(0);
						}else
						if($shift_second_half >= $out_date_time || $import_out_date < $out_date_time){
							echo $this->returnResult(FALSE, 'Please Map to Correct Out Date or OutTime!', [], []);
							exit(0);
						}else
						if($full_work_hour > $total_time){
							echo $this->returnResult(FALSE, 'Total Time should not Lesser than Full Day Work Hours..!!', [], []);
							exit(0);
						}else{
							return true;
						}
					}else
					if($day_type === 2){

						if($shift_first_half <= $in_date_time || $import_in_date > $in_date_time){
							echo $this->returnResult(FALSE, 'Please Check to Correct In Date or Time!', [], []);
							exit(0);
						}else
						if($shift_form_date >= $out_date_time || $shift_to_date <= $out_date_time || $import_out_date < $out_date_time){
							echo $this->returnResult(FALSE, 'Please Check to Correct Out Date or Time!', [], []);
							exit(0);
						}else
						if($half_work_hour > $total_time){
							echo $this->returnResult(FALSE, 'Total Time should not Lesser than Half Day Work Hours..!!', [], []);
							exit(0);
						}else{
							return true;
						}
					}else{
						if($shift_from_date >= $in_date_time || $shift_to_date <= $in_date_time || $import_in_date > $in_date_time){
							echo $this->returnResult(FALSE, 'Please Check to Correct In Date or Time!', [], []);
							exit(0);
						}else
						if($shift_second_half >= $out_date_time || $import_out_date < $out_date_time){
							echo $this->returnResult(FALSE, 'Please Check to Correct Out Date or Time!', [], []);
							exit(0);
						}else
						if($half_work_hour > $total_time){
							echo $this->returnResult(FALSE, 'Total Time should not Lesser than Half Day Work Hours..!!', [], []);
							exit(0);
						}else{
							return true;
						}	
					}
				}	
			}
		}else{
			echo $this->returnResult(FALSE, 'Already Transaction Exist with the current Shift.! Please Cancel the Previous Transaction and try Again.!', [], []);
			exit(0);
		}
	}
	// FUNCTION FOR PERMISSION ENTRY TYPE
	public function permission_entry($post_data,$form_id,$prime_financial_id){
		$leave_financial_info          = $this->get_leave_financial_details();
		$prime_leave_financial_year_id = $leave_financial_info[0]->prime_leave_financial_year_id;
		$approval_insert_key           = "";
		$approval_insert_value         = "";
		$approval_update_qry           = "";
		$print_type_id                 = "";
		$created_on                    = date("Y-m-d H:i:s");    
		foreach ($post_data as $key => $value) {
			if($key === "request_date"){
				$key = "applied_on";
			}
			if($key === "from_date"){
				$from_date = $value;
			}
			if($key === "to_date"){
				$to_date = $value;
			}
			if($key === "first_level_approval"){
				$current_control = $value;
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_approve_type"){
				$leave_approve_type = $value;
			}
			if($key === "second_level_approval"){
				$second_level_approval = $value;
			}

			$approval_insert_key     .= $key.",";
			$approval_insert_value   .= '"'.$value.'",';
			$approval_update_qry   .= $key.' = "'.$value.'",';		
		}
		
		if((int)$request_type === 4 || (int)$request_type === 5){
			$component_value  = $post_data["component_value"];
			$employee_code    = $post_data["employee_code"];
			$permission_date  = $post_data["permission_date"];
			$shift_name 	  = $post_data["shift_name"];
			$permission_type  = $post_data["permission_type"];
			$from_date_type   = $post_data["from_date_type"];
			$to_date_type 	  = $post_data["to_date_type"];
			$in_time          = $post_data["in_time"];
			$out_time         = $post_data["out_time"];
			$total_time       = $post_data["total_time"];
			$leave_status     = $post_data["leave_status"] ?? 1;
			$total_time_arr   = explode(':', $total_time ?? "");
    		$total_minute     = round(($total_time_arr[0]*60) + ($total_time_arr[1]));

			$permission_entry_value = '("'.$component_value.'","'.$employee_code.'","'.$prime_leave_financial_year_id.'","'.$permission_date.'","'.$shift_name.'","'.$permission_type.'","'.$in_time.'","'.$out_time.'","'.$total_time.'","'.$total_minute.'","'.$form_id.'","'.$leave_status.'","'.$this->logged_id.'","'.date("Y-m-d H:i:s").'")';
			
			$request_permission_insert_qry 	  = "INSERT into cw_permission_entry (component_value,employee_code,financial_setting_id,permission_date,shift_name,permission_type,in_time,out_time,total_time,total_minute,prime_request_id,leave_status,trans_created_by,trans_created_date) values $permission_entry_value";
			$request_permission_insert_info   = $this->runQuery_insert_id($request_permission_insert_qry);

			if(!empty($request_permission_insert_info)){
				$approval_insert_key     .= "current_control,prime_request_id,financial_setting_id,trans_created_by,trans_created_date";
				$approval_insert_value   .= '"'.$current_control.'","'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$this->logged_id.'","'.$created_on.'"';

				$approval_insert_query    = "insert into cw_approval (".$approval_insert_key.") values (".$approval_insert_value.")";
				$approval_insert_info     = $this->runQuery_insert_id($approval_insert_query);
				//$approval_insert_result   =  $this->result($approval_insert_info);
			}
			$employee_detail_qry  		  = 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
			$employee_detail_info  	      = $this->runQuery($employee_detail_qry);
			$employee_detail_result       =  $this->result($employee_detail_info);
			$view_id 					  = $employee_detail_result[0]->prime_employees_id;
			$first_level_approval_code	  = $employee_detail_result[0]->first_level_approval;
			$second_level_approval_code	  = $employee_detail_result[0]->second_level_approval;

			$first_approval_qry  		  = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
			$first_approval_info  	      = $this->runQuery($first_approval_qry);
			$first_approval_result        =  $this->result($first_approval_info);
			$first_approval_mail 		  = $first_approval_result[0]->company_email_id;

			$second_approval_qry  		  = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
			$second_approval_info  	      = $this->runQuery($second_approval_qry);
			$second_approval_result  	  =  $this->result($second_approval_info);
			$second_approval_mail 		  = $second_approval_result[0]->company_email_id;

			$print_type_id = 27;
			if((int)$leave_approve_type === 1){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
			}else
			if((int)$leave_approve_type === 2){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
			}else
			if((int)$leave_approve_type === 3){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
			}else
			if((int)$leave_approve_type === 4){
				return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
			}		
		}		
	}
	// FUNCTION FOR SHIFT CHANGE TYPE
	public function shift_change_entry($post_data,$form_id,$prime_financial_id){
		$leave_financial_info          = $this->get_leave_financial_details();
		$prime_leave_financial_year_id = $leave_financial_info[0]->prime_leave_financial_year_id;
		
		$approval_insert_key      = "";
		$approval_insert_value    = "";
		$approval_update_qry      = "";
		$created_on               = date("Y-m-d H:i:s");    

		foreach ($post_data as $key => $value) {
			if($key === "request_date"){
				$key        = "applied_on";
			}
			if($key === "shift_date"){
				$shift_date = $value;
			}
			if($key === "current_shift"){
				$current_shift = $value;
			}
			if($key === "change_shift"){
				$change_shift = $value;
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_approve_type"){
				$leave_approve_type = $value;
			}
			if($key === "first_level_approval"){
				$current_control = $value;
			}
			if($key === "employee_code"){
				$employee_code = $value;
			}

			$approval_insert_key     .= $key.",";
			$approval_insert_value   .= '"'.$value.'",';
			$approval_update_qry     .= $key.' = "'.$value.'",';	
		}
		$approval_insert_key     .= "current_control,prime_request_id,financial_setting_id,trans_created_by,trans_created_date";
		$approval_insert_value   .= '"'.$current_control.'","'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$this->logged_id.'","'.$created_on.'"';

		$approval_insert_query = "insert into cw_approval (".$approval_insert_key.") values (".$approval_insert_value.")";
		$approval_insert_info  = $this->runQuery_insert_id($approval_insert_query);
		if($approval_insert_info){
			$employee_detail_qry  		 = 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
			$employee_detail_info  	     = $this->runQuery($employee_detail_qry);
			$employee_detail_result      =  $this->result($employee_detail_info);
			$view_id 					 = $employee_detail_result[0]->prime_employees_id;
			$first_level_approval_code	 = $employee_detail_result[0]->first_level_approval;
			$second_level_approval_code	 = $employee_detail_result[0]->second_level_approval;

			$first_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
			$first_approval_info  	     = $this->runQuery($first_approval_qry);
			$first_approval_result       =  $this->result($first_approval_info);
			$first_approval_mail 		 = $first_approval_result[0]->company_email_id;

			$second_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
			$second_approval_info  	     = $this->runQuery($second_approval_qry);
			$second_approval_result  	 =  $this->result($second_approval_info);
			$second_approval_mail 		 = $second_approval_result[0]->company_email_id;

			$print_type_id               = 39;	
			if((int)$leave_approve_type === 1){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
			}else
			if((int)$leave_approve_type === 2){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
			}else
			if((int)$leave_approve_type === 3){
				return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
			}else
			if((int)$leave_approve_type === 4){
				return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
			}
		}	
	}
	// FUNCTION FOR MANUAL PUNCH TYPE
	public function manual_punch_entry($post_data,$form_id,$prime_financial_id){
		$leave_financial_info            = $this->get_leave_financial_details();
		$prime_leave_financial_year_id   = $leave_financial_info[0]->prime_leave_financial_year_id;
		$approval_insert_key             = "";
		$approval_insert_value           = "";
		$approval_update_qry             = "";
		$created_on                      = date("Y-m-d H:i:s");          
		foreach ($post_data as $key => $value) {
			if($key === "request_date"){
				$key  = "applied_on";
			}
			if($key === "component_value"){
				$component_value = $value;
			}
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "shift_date"){
				$shift_date  = $value;
			}
			if($key === "in_date"){
				$in_date     = $value;
			}
			if($key === "out_date"){
				$out_date = $value;
			}
			if($key === "shift_name"){
				$shift_name = $value;
			}
			if($key === "day_type"){
				$day_type = $value;
			}
			if($key === "in_time"){
				$in_time = $value;
			}
			if($key === "out_time"){
				$out_time = $value;
			}
			if($key === "total_time"){
				$total_time = $value;
			}
			if($key === "leave_status"){
				$leave_status = $value;
			}
			if($key === "mp_reason"){
				$mp_reason = $value;
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_approve_type"){
				$leave_approve_type = $value;
			}
			if($key === "first_level_approval"){
				$current_control = $value;
			}
			if($key === "second_level_approval"){
				$second_level_approval = $value;
			}
			$approval_insert_key     .= $key.",";
			$approval_insert_value   .= '"'.$value.'",';
			$approval_update_qry     .= $key.' = "'.$value.'",';	
		}
		//Manual punch insert query
		$manual_punch_val      = '("'.$form_id.'","'.$prime_financial_id.'","'.$component_value.'",'.'"'.$employee_code.'",'.'"'.$shift_name.'",'.'"'.$shift_date.'",'.'"'.$in_date.'",'.'"'.$out_date.'",'.'"'.$in_time.'",'.'"'.$out_time.'",'.'"'.$total_time.'",'.'"'.$day_type.'","1","'.$mp_reason.'",'.'"'.$this->logged_id.'",'.'"'.$created_on.'")';

		$manual_punch_ins_qry  = "INSERT into cw_manual_punch_entry (prime_request_id,financial_setting_id,component_value,employee_code,shift_name,shift_date,in_date,out_date,in_time,out_time,total_time,day_type,leave_status,mp_reason,trans_created_by,trans_created_date) values $manual_punch_val";
		$manual_punch_ins_info = $this->runQuery_insert_id($manual_punch_ins_qry);

		if($manual_punch_ins_info){
			$approval_insert_key     .= "current_control,prime_request_id,financial_setting_id,trans_created_by,trans_created_date";
			$approval_insert_value   .= '"'.$current_control.'","'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$this->logged_id.'","'.$created_on.'"';
			$approval_insert_query    = "insert into cw_approval (".$approval_insert_key.") values (".$approval_insert_value.")";
			$approval_insert_info     = $this->runQuery_insert_id($approval_insert_query);
		}

		$employee_detail_qry  		 = 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info  	     = $this->runQuery($employee_detail_qry);
		$employee_detail_result      = $this->result($employee_detail_info);
		$view_id 					 = $employee_detail_result[0]->prime_employees_id;
		$first_level_approval_code	 = $employee_detail_result[0]->first_level_approval;
		$second_level_approval_code	 = $employee_detail_result[0]->second_level_approval;

		$first_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
		$first_approval_info  	     = $this->runQuery($first_approval_qry);
		$first_approval_result       =  $this->result($first_approval_info);
		$first_approval_mail 		 = $first_approval_result[0]->company_email_id;

		$second_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
		$second_approval_info  	     = $this->runQuery($second_approval_qry);
		$second_approval_result  	 =  $this->result($second_approval_info);
		$second_approval_mail 		 = $second_approval_result[0]->company_email_id;

		$print_type_id               = 45;
		if((int)$leave_approve_type === 1){
			return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
		}else
		if((int)$leave_approve_type === 2){
			return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
		}else
		if((int)$leave_approve_type === 3){
			return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
		}else
		if((int)$leave_approve_type === 4){
			return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
		}
	}
	//LEAVE ENTRY FUNCTION
	public function leave_entry($post_data,$form_id,$prime_financial_id){
		$leave_financial_info          = $this->get_leave_financial_details();
		$prime_leave_financial_year_id = $leave_financial_info[0]->prime_leave_financial_year_id;
		$approval_insert_key           = "";
		$approval_insert_value         = "";
		$approval_update_qry           = "";
		$print_type_id                 = "";
		$created_on                    = date("Y-m-d H:i:s");    
		foreach ($post_data as $key => $value){
			if($key === "employee_code"){
				$employee_code = $value;
			}
			if($key === "request_date"){
				$key = "applied_on";
			}
			if($key === "from_date"){
				$from_date = $value;
			}
			if($key === "to_date"){
				$to_date = $value;
			}
			if($key === "first_level_approval"){
				$current_control = $value;
			}
			if($key === "request_type"){
				$request_type = $value;
			}
			if($key === "leave_approve_type"){
				$leave_approve_type = $value;
			}
			if($key === "second_level_approval"){
				$second_level_approval = $value;
			}
			if($key !== "no_of_days"){
				$approval_insert_key     .= $key.",";
				$approval_insert_value   .= '"'.$value.'",';
				$approval_update_qry   .= $key.' = "'.$value.'",';
			}			
		}
		$employee_detail_qry  		 = 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
		$employee_detail_info  	     = $this->runQuery($employee_detail_qry);
		$employee_detail_result      =  $this->result($employee_detail_info);
		$view_id 					 = $employee_detail_result[0]->prime_employees_id;
		$first_level_approval_code	 = $employee_detail_result[0]->first_level_approval;
		$second_level_approval_code	 = $employee_detail_result[0]->second_level_approval;

		$first_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
		$first_approval_info  	     = $this->runQuery($first_approval_qry);
		$first_approval_result       =  $this->result($first_approval_info);
		$first_approval_mail 		 = $first_approval_result[0]->company_email_id;

		$second_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
		$second_approval_info  	     = $this->runQuery($second_approval_qry);
		$second_approval_result  	 =  $this->result($second_approval_info);
		$second_approval_mail 		 = $second_approval_result[0]->company_email_id;
		
		$from_date_diff  = strtotime($from_date);
		$to_date_diff    = strtotime($to_date);
		$datediff        = $to_date_diff - $from_date_diff;
		$no_of_days      = round($datediff / (60 * 60 * 24));	
		if((int)$request_type === 1 || (int)$request_type === 2 || (int)$request_type === 3 || (int)$request_type === 8){
			$employee_code   = $post_data["employee_code"];
			$from_date_type  = $post_data["from_date_type"];
			$to_date_type 	 = $post_data["to_date_type"];
			$component_value = $post_data["component_value"];
			$leave_type      = $post_data["leave_type"];
			$from_date       = $post_data["from_date"];
			$to_date         = $post_data["to_date"];
			$startTimeStamp  = strtotime($from_date);
			$endTimeStamp    = strtotime($to_date);
			$timeDiff        = abs($endTimeStamp - $startTimeStamp);
			$numberDays      = $timeDiff/86400;  // 86400 seconds in one day
			// and you might want to convert to integer
			$numberDays      = intval($numberDays);
			$numberDays      = (int)$numberDays + 1;
			$date_range      = $this->getDatesFromRange($from_date, $to_date);
			$get_year        = date('Y',strtotime($from_date));

			//FOR MAIL FUNCTION
			$employee_detail_qry  		 = 'select prime_employees_id,first_level_approval,second_level_approval from cw_employees where employee_code = "'.$employee_code.'" and trans_status = 1';
			$employee_detail_info  	     = $this->runQuery($employee_detail_qry);
			$employee_detail_result      =  $this->result($employee_detail_info);
			$view_id 					 = $employee_detail_result[0]->prime_employees_id;
			$first_level_approval_code	 = $employee_detail_result[0]->first_level_approval;
			$second_level_approval_code	 = $employee_detail_result[0]->second_level_approval;

			$first_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$first_level_approval_code.'" and trans_status = 1';
			$first_approval_info  	     = $this->runQuery($first_approval_qry);
			$first_approval_result       =  $this->result($first_approval_info);
			$first_approval_mail 		 = $first_approval_result[0]->company_email_id;

			$second_approval_qry  		 = 'select company_email_id from cw_employees where employee_code = "'.$second_level_approval_code.'" and trans_status = 1';
			$second_approval_info  	     = $this->runQuery($second_approval_qry);
			$second_approval_result  	 =  $this->result($second_approval_info);
			$second_approval_mail 		 = $second_approval_result[0]->company_email_id;

			//for Get Leave Creation
			$leave_creation_qry    = 'SELECT count(*) as creation_count,leave_opening,intervening_holidays,intervening_type,leave_name,coff,coff_late from cw_leave_creation where cw_leave_creation.trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
			$leave_creation_info   = $this->runQuery($leave_creation_qry);
			$leave_creation_result =  $this->result($leave_creation_info);
			$leave_opening         = $leave_creation_result[0]->leave_opening;	
			$intervening_holidays  = $leave_creation_result[0]->intervening_holidays;
			$intervening_type      = explode(",",$leave_creation_result[0]->intervening_type ?? "");
			$leave_name  		   = $leave_creation_result[0]->leave_name;
			$leave_name 		   = strtolower($leave_name);
			$creation_count 	   = $leave_creation_result[0]->creation_count;
			$coff 	               = $leave_creation_result[0]->coff;
			$coff_late 	           = $leave_creation_result[0]->coff_late;
			$pending_column 	   = "pending_".$leave_name;
			/*if((int)$coff_late === 1){ // For Coff Late created for Rebar
				if(($from_date === $to_date) && $from_date_type === 1 && $to_date_type === 1){
					$this->check_coff_late($employee_code,$from_date);
				}else{
					echo json_encode(array('success' => FALSE, 'message' => "Coff Late will be available for the Next Day first Half only.."));
					exit(0);
				}				
			}*/
			//SELECT QUERY FOR CHECK A GENENRAL SETTING PARAMETER BASED TYPE
			$param_based_type_qry  = 'SELECT parameter_type,based_on,check_parameter FROM cw_general_setting inner join cw_parameter_type on cw_parameter_type.prime_parameter_type_id = cw_general_setting.entry_parameter_type WHERE cw_general_setting.trans_status = 1';
			$param_based_type_info = $this->runQuery($param_based_type_qry);
			$param_based_type_rslt = $this->result_array($param_based_type_info);

			$param_based_type_arr  = array();
			$check_parameter_arr   = array();
			foreach ($param_based_type_rslt as $arr) {
				$param_based_type_arr[$arr['parameter_type']] = $arr['based_on'];
				$check_parameter_arr[$arr['parameter_type']]  = $arr['check_parameter'];
			}
			$week_off_entry        = (int)$param_based_type_arr['Weekly off Entry'];	
			$holiday_entry         = (int)$param_based_type_arr['Holiday Entry'];	
			$leave_entry           = (int)$param_based_type_arr['Leave Entry'];
			//CONDITION FOR CHECK A HOLIDAY DATE FOR PARAMETER TYPE BASED ON
			if($holiday_entry === 2){
				$holid_component_query  = 'SELECT pick_table,pick_list,components,label_name FROM cw_general_setting inner join cw_form_setting on cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 2 and cw_general_setting.trans_status = 1';
				$holid_component_info   = $this->runQuery($holid_component_query);
				$holid_component_result =  $this->result($holid_component_info);
				$holid_pick_list        = $holid_component_result[0]->pick_list;
				// $holid_pick_table = $holid_component_result[0]->pick_table;
				// $holid_components = $holid_component_result[0]->components;
				$holid_pick_list_val    = explode(",",$holid_pick_list ?? "");
				$holid_label_name       = $holid_component_result[0]->label_name;
				//$holid_comp_value     = $this->emp_pick_arr[$employee_code][$holid_label_name];
				$emp_pick_arr           = $this->get_emp_data($employee_code);
				$holid_comp_value       = $emp_pick_arr[$employee_code][$holid_label_name];				
				//for Get Hollidays
				$holiday_qry            = 'select cw_holiday_entry_holiday_data.holiday_date from cw_holiday_entry inner join cw_holiday_entry_holiday_data on cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id where FIND_IN_SET("'.$holid_comp_value.'", cw_holiday_entry_holiday_data.component_value) and cw_holiday_entry.holiday_year = "'.$get_year.'" and cw_holiday_entry.trans_status = 1 and cw_holiday_entry_holiday_data.trans_status = 1';
				$holiday_info           = $this->runQuery($holiday_qry);
				$holiday_result         = $this->result_array($holiday_info);
			
				$holiday_result         = array_reduce($holiday_result ?? [], function($result, $arr){			
				    $result[$arr['holiday_date']] = $arr;
				    return $result;
				}, array());
				$valid_required  = (int)$check_parameter_arr['Weekly off Entry'];
				if($valid_required === 1){
					if($holiday_result[$from_date]){
						echo $this->returnResult(FALSE, 'Requested Date is Holiday,Request Not accepted...!', [], []);
						exit(0);
					}
				}
			}
			
			//CONDITION FOR CHECK A WEEKOFF DATE FOR PARAMETER TYPE BASED ON
			if($week_off_entry === 1){
				$check_weekoff_qry   = 'SELECT employee_code,weekoff_date,weekoff_type from cw_weekoff_import WHERE employee_code = "'. $employee_code .'" and weekoff_date >= "'.$from_date.'" and weekoff_date <= "'.$to_date.'" and financial_setting_id = '.$prime_financial_id.' and trans_status = 1';
				$check_weekoff_info   = $this->runQuery($check_weekoff_qry);
				$check_weekoff_rlst   = $this->result_array($check_weekoff_info);

				$weekoff_result       = array_reduce($check_weekoff_rlst ?? [], function($result, $arr){			
				    $result[$arr['employee_code']][$arr['weekoff_date']] = $arr['weekoff_type'];
				    return $result;
				}, array());
				$valid_required  = (int)$check_parameter_arr['Weekly off Entry'];
				if($valid_required === 1){
					if($holiday_result[$from_date]){
						echo $this->returnResult(FALSE, 'Requested Date is Week off,Request Not accepted...!', [], []);
						exit(0);
					}
				}
			}else
			if($week_off_entry === 2){
				$week_component_query  = 'SELECT pick_table,pick_list,components,label_name FROM cw_general_setting inner join cw_form_setting on cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 1 and cw_general_setting.trans_status = 1';
				$week_component_info   = $this->runQuery($week_component_query);
				$week_component_result =  $this->result($week_component_info);
				$week_pick_list   = $week_component_result[0]->pick_list;
				$week_pick_list_val   = explode(",",$week_pick_list ?? "");
				$week_pick_list_val_1 = $week_pick_list_val[0];
				$week_pick_list_val_2 = $week_pick_list_val[1];

				$week_label_name       = $week_component_result[0]->label_name;
				//$week_comp_value       = $this->emp_pick_arr[$employee_code][$week_label_name];
				$emp_pick_arr          = $this->get_emp_data($employee_code);
				$week_comp_value       = $emp_pick_arr[$employee_code][$week_label_name];
				/* Weekoff - START */
				$weekoff_qry = 'select cw_weekoff_entry_weekoff_days_details.weekday,cw_weekoff_entry_weekoff_days_details.first_week,cw_weekoff_entry_weekoff_days_details.second_week,cw_weekoff_entry_weekoff_days_details.third_week,cw_weekoff_entry_weekoff_days_details.fourth_week,cw_weekoff_entry_weekoff_days_details.fifth_week from cw_weekoff_entry inner join cw_weekoff_entry_weekoff_days_details on cw_weekoff_entry_weekoff_days_details.prime_weekoff_entry_id = cw_weekoff_entry.prime_weekoff_entry_id where FIND_IN_SET("'.$week_comp_value.'", cw_weekoff_entry.component_value) and cw_weekoff_entry.from_date <= "'.$from_date.'" AND cw_weekoff_entry.to_date >= "'.$to_date.'" and cw_weekoff_entry.trans_status = 1 and cw_weekoff_entry_weekoff_days_details.trans_status = 1';
				$weekoff_info   = $this->runQuery($weekoff_qry);
				$weekoff_result    = $this->result_array($weekoff_info);

				$weekoff_result = array_reduce($weekoff_result ?? [], function($result, $arr){			
				$result[$arr['weekday']] = $arr;
				    return $result;
				}, array());
				$valid_required  = (int)$check_parameter_arr['Weekly off Entry'];
				if($valid_required === 1){
					if($holiday_result[$from_date]){
						echo $this->returnResult(FALSE, 'Requested Date is Week off,Request Not accepted...!', [], []);
						exit(0);
					}
				}
				/* Weekoff - END */
				$days_arr = array("sun"=>1,"mon"=>2,"tue"=>3,"wed"=>4,"thu"=>5,"fri"=>6,"sat"=>7);
				$week_arr = array(1=>"first_week",2=>"second_week",3=>"third_week",4=>"fourth_week",5=>"fifth_week");
			}
			$from_date_count   = 0;
			$to_date_count     = 0;
			$leave_entry_value = ""; 
			if((int)$request_type === 1){
				if(!$leave_balance){
					$leave_balance =10;
				}
				if((int)$intervening_holidays === 1 && in_array("1",$intervening_type)){
					//Check before from date
					for($j=1;$j<=(int)$leave_balance;$j++){
						$date          = new DateTime($from_date);
						$date->modify("-$j day");
						$check_prev    = $date->format("Y-m-d");
						//WEEKOFF DATE CHECK
						if($week_off_entry === 1){
							$weekoff_value = (int)$weekoff_result[$employee_code][$check_prev];		
						}else
						if($week_off_entry === 2){
							$get_day       = strtolower(date('D',strtotime($check_prev)));
							$day           = $days_arr[$get_day];
							$week_no       = $this->weekOfMonth(strtotime($check_prev)); 
							$week          = $week_arr[$week_no];
							$weekoff_value = $weekoff_result[$day][$week];			
						}
						//HOLIDAY DATE CHECK
						if($holiday_entry === 2){
							$prev_holiday  = $holiday_result[$check_prev]['holiday_date'];
						}	
						if($prev_holiday ||  $weekoff_value){
							$from_date_count = $from_date_count + 1;
							if($from_date_count){
								$leave_entry_value .= '("'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$component_value.'",'.'"'.$employee_code.'",'.'"'.$check_prev.'",'.'"'.$leave_type.'",'.'"1",'.'"1",'.'"1",'.'"'.$this->logged_id.'",'.'"'.date("Y-m-d H:i:s").'"),';
							}					
						}else{
							break;
						}									
					}
				}
				$end_key       = end(array_keys($date_range ?? []));
				$leave_count   = 0;
				$total_leave   = 0;
				foreach ($date_range as $key => $common_date){
					//WEEKOFF DATE CHECK
					if($week_off_entry === 1){
						$weekoff_value      = (int)$weekoff_result[$employee_code][$common_date];		
					}else
					if($week_off_entry === 2){
						$get_day            = strtolower(date('D',strtotime($common_date)));
						//Check weekoff day exist
						$day                = $days_arr[$get_day];
						$week_no            = $this->weekOfMonth(strtotime($common_date)); 
						$week               = $week_arr[$week_no];
						$weekoff_value      = $weekoff_result[$day][$week];	
					}
					//HOLIDAY DATE CHECK
					if($holiday_entry === 2){
						$get_common_holiday = $holiday_result[$common_date]['holiday_date'];
					}	
					if($key === 0){
						if((int)$from_date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$from_date_type === 2 || (int)$from_date_type === 3){
							$leave_count = 0.50;
						}
						$date_type       = $from_date_type;
					}else
					if($key === $end_key){						
						if((int)$to_date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$to_date_type === 2 || (int)$to_date_type === 3){
							$leave_count = 0.50;
						}
						$date_type       = $to_date_type;
					}else{
						
						if(((int)$weekoff_value === 1 || $get_common_holiday)){
							if(in_array("3",$intervening_type)){
								$leave_count = 1.00;
								$date_type   = 1;									
							}else{
								$leave_count = 0;
							}						
						}else{
							$leave_count = 1.00;
							$date_type   = 1;
						}
					}

					if((int)$weekoff_value === 1 && (int)$intervening_holidays === 1 && in_array("3",$intervening_type)){
						/* updated for TCL */
						if((int)$date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$date_type === 2 || (int)$date_type === 3){
							$leave_count = 0.50;
						}
						/* updated for TCL */
					}else
					if(((int)$weekoff_value === 2 || (int)$weekoff_value === 3) && (int)$intervening_holidays === 1 && in_array("3",$intervening_type)){
						$leave_count = 0.50;
					}else
					if((int)$intervening_holidays !== 1 && (int)$weekoff_value === 1){
						$leave_count = 0;
					}else
					if((int)$intervening_holidays !== 1 && ((int)$weekoff_value === 2 || (int)$weekoff_value === 3)){
						$leave_count = 0.50;
					}

					if($get_common_holiday && $intervening_holidays === 1 && in_array("3",$intervening_type)){
						if((int)$date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$date_type === 2 || (int)$date_type === 3){
							$leave_count = 0.50;
						}
					}else
					if((int)$intervening_holidays !== 1 && (int)$get_common_holiday){
						$leave_count = 0;
					}	
					$total_leave = $total_leave + $leave_count;

					if($leave_count > 0){
						$leave_entry_value .= '("'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$component_value.'",'.'"'.$employee_code.'",'.'"'.$common_date.'",'.'"'.$leave_type.'",'.'"'.$leave_count.'",'.'"'.$date_type.'",'.'"1",'.'"'.$this->logged_id.'",'.'"'.date("Y-m-d H:i:s").'"),';
					}
				}
				if((int)$intervening_holidays === 1 && in_array("2",$intervening_type)){
					//Check after todate
					for($i=1;$i<=(int)$leave_balance;$i++){			
						$after_date = new DateTime($to_date);
						$after_date->modify("$i day");
						$check_after = $after_date->format("Y-m-d");
						//WEEKOFF DATE CHECK
						if($week_off_entry === 1){
							$after_weekoff_value = (int)$weekoff_result[$employee_code][$check_after];		
						}else
						if($week_off_entry === 2){
							$get_after_day       = strtolower(date('D',strtotime($check_after)));
							$after_day           = $days_arr[$get_after_day];
							$after_week_no       = $this->weekOfMonth(strtotime($check_after)); 
							$after_week          = $week_arr[$after_week_no];
							$after_weekoff_value = $weekoff_result[$after_day][$after_week];		
						}
						//HOLIDAY DATE CHECK
						if($holiday_entry === 2){
							$after_holiday  = $holiday_result[$check_after]['holiday_date'];
						}	
						if($after_holiday || $after_weekoff_value){
							$to_date_count = $to_date_count + 1;
							if($to_date_count){
								$leave_entry_value .= '("'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$component_value.'",'.'"'.$employee_code.'",'.'"'.$check_after.'",'.'"'.$leave_type.'",'.'"1",'.'"1",'.'"1",'.'"'.$this->logged_id.'",'.'"'.date("Y-m-d H:i:s").'"),';
							}
						}else{
							break;
						}	
					}	
				}

				$total_leave = $total_leave + $from_date_count + $to_date_count;
				$leave_entry_value = rtrim($leave_entry_value,",");

				if((int)$creation_count === 0){
					echo $this->returnResult(FALSE, 'Leave Creation Not Available', [], []);
					exit(0);
				}else{	
					$leave_opening_count      = "";
					if((int)$leave_opening === 1){
						$get_old_used_qry 	  = 'select count(*) as leave_opening_count,'.$pending_column.' from cw_leave_opening where employee_code = "'.$employee_code.'" and financial_setting_id = "'.$prime_leave_financial_year_id.'" and trans_status = 1';
						$get_old_used_info    = $this->runQuery($get_old_used_qry);
						$get_old_used_result  =  $this->result($get_old_used_info);
						$leave_opening_count  = $get_old_used_result[0]->leave_opening_count;
						$pending_leave_count  = $get_old_used_result[0]->$pending_column;
					}else{
						$leave_opening_count = 1;
					}					
					if((int)$leave_opening_count === 0){
						echo $this->returnResult(FALSE, 'Leave Opening Not Available !', [], []);
						exit(0);
					}else{
						if($leave_entry_value){
							$request_leave_insert_qry 	 = "INSERT into cw_leave_entry (prime_request_id,financial_setting_id,component_value,employee_code,leave_date,leave_type,leave_count,date_type,leave_status,trans_created_by,trans_created_date) values $leave_entry_value";
							$leave_entry_ins_count       = $this->runQuery_insert_id($request_leave_insert_qry);
							// if($request_leave_entry)
							if($leave_entry_ins_count){
								$approval_insert_key     .= "current_control,no_of_days,prime_request_id,financial_setting_id,trans_created_by,trans_created_date";
								$approval_insert_value   .= '"'.$current_control.'","'.$total_leave.'","'.$form_id.'","'.$prime_financial_id.'","'.$this->logged_id.'","'.$created_on.'"';

								$approval_insert_query = "insert into cw_approval (".$approval_insert_key.") values (".$approval_insert_value.")";
								$approval_insert_info  = $this->runQuery_insert_id($approval_insert_query);
								//$approval_insert_result  =  $this->result($approval_insert_info);
							
								if((int)$leave_opening === 1) {
									$total_leave  = $pending_leave_count + $total_leave;			
									$upd_leave_opening = 'UPDATE cw_leave_opening SET '.$pending_column.' = "'.$total_leave.'",trans_updated_by = "'.$this->logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and cw_leave_opening.financial_setting_id = "'.$prime_leave_financial_year_id.'" and cw_leave_opening.trans_status = 1';
									$this->runQuery($upd_leave_opening);
								}

								$print_type_id = 21;
								if((int)$leave_approve_type === 1){
									return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
								}else
								if((int)$leave_approve_type === 2){
									return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
								}else
								if((int)$leave_approve_type === 3){
									return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
								}else
								if((int)$leave_approve_type === 4){
									return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
								}
							}
						}
					}
				}	
			}else
			if((int)$request_type === 3 || (int)$request_type === 8){
				$business_trip     = 0;
				if((int)$request_type === 8){
					$business_trip = 1;
				}
				$end_key             = end(array_keys($date_range ?? []));
				$leave_count         = 0;
				$total_leave         = 0;
				$on_duty_entry_value = "";
				foreach ($date_range as $key => $common_date){
					//WEEKOFF DATE CHECK
					if($week_off_entry === 1){
						$weekoff_value      = (int)$weekoff_result[$employee_code][$common_date];		
					}else
					if($week_off_entry === 2){
						$get_day            = strtolower(date('D',strtotime($common_date)));
						//Check weekoff day exist
						$day                = $days_arr[$get_day];
						$week_no            = $this->weekOfMonth(strtotime($common_date)); 
						$week               = $week_arr[$week_no];
						$weekoff_value      = $weekoff_result[$day][$week];	
					}
					//HOLIDAY DATE CHECK
					if($holiday_entry === 2){
						$get_common_holiday = $holiday_result[$common_date]['holiday_date'];
					}	
					if($key === 0){
						if((int)$from_date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$from_date_type === 2 || (int)$from_date_type === 3){
							$leave_count = 0.50;
						}
						$date_type       = $from_date_type;
					}else
					if($key === $end_key){
						if((int)$to_date_type === 1){
							$leave_count = 1.00;
						}else
						if((int)$to_date_type === 2 || (int)$to_date_type === 3){
							$leave_count = 0.50;
						}
						$date_type       = $to_date_type;
					}else{
						$leave_count = 1.00;
						$date_type   = 1;
						
					}
					$total_leave = $total_leave + $leave_count;
					if($leave_count > 0){
						$on_duty_entry_value .= '("'.$form_id.'","'.$prime_leave_financial_year_id.'","'.$component_value.'","'.$employee_code.'","'.$common_date.'","'.$leave_count.'","'.$date_type.'","'.$business_trip.'","1","'.$this->logged_id.'","'.date("Y-m-d H:i:s").'"),';
					}
				}
				$on_duty_entry_value = rtrim($on_duty_entry_value,",");
				if($on_duty_entry_value){
					$request_on_duty_insert_qry    = "INSERT into cw_on_duty_entry (prime_request_id,financial_setting_id,component_value,employee_code,on_duty_date,on_duty_count,date_type,business_trip,on_duty_status,trans_created_by,trans_created_date) values $on_duty_entry_value";
					$on_duty_entry_ins_count       = $this->runQuery_insert_id($request_on_duty_insert_qry);
					if($on_duty_entry_ins_count){
						$approval_insert_key     .= "current_control,no_of_days,prime_request_id,financial_setting_id,trans_created_by,trans_created_date";
						$approval_insert_value   .= '"'.$current_control.'","'.$total_leave.'","'.$form_id.'","'.$prime_financial_id.'","'.$this->logged_id.'","'.$created_on.'"';

						$approval_insert_query = "insert into cw_approval (".$approval_insert_key.") values (".$approval_insert_value.")";
						$this->runQuery_insert_id($approval_insert_query);
						//$approval_insert_result  =  $this->result($approval_insert_info);

						$print_type_id = 33;
						if((int)$leave_approve_type === 1){
							return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
						}else
						if((int)$leave_approve_type === 2){
							return $this->send_mail($print_type_id,$form_id,$first_approval_mail,$second_approval_mail);
						}else
						if((int)$leave_approve_type === 3){
							return $this->send_mail($print_type_id,$form_id,$first_approval_mail,"");
						}else
						if((int)$leave_approve_type === 4){
							return $this->send_mail($print_type_id,$form_id,"",$second_approval_mail);
						}
					}	
				}
			}		
		}		
	}

	public function common_validation($post_data){				
		$request_type          = (int)$post_data["request_type"];
		$employee_code         = $post_data["employee_code"];	
		$device_code           = $post_data["device_code"];		
		$company_info          = $this->company_info();
		$mp_treat_time_log     = $company_info[0]->mp_treat_as;

		if($request_type === 1 || $request_type === 3 || $request_type === 8){
			$from_date         = $post_data['from_date'];  
			$to_date           = $post_data["to_date"];
			$from_date_type    = (int)$post_data["from_date_type"];
			$to_date_type      = (int)$post_data["to_date_type"];  
		}else
		if($request_type === 4 || $request_type === 5){
			$from_date         = $post_data['permission_date'];
			$to_date           = $post_data['permission_date'];
		}else
		if($request_type === 7){
			$shift_date        = date("Y-m-d",strtotime($post_data["shift_date"]));
			//$to_date           = date("Y-m-d",strtotime($post_data["shift_date"]));
			$in_date 	       = date("Y-m-d",strtotime($post_data["in_date"]));
            $in_time           = $post_data["in_time"];
            $out_date 	       = date("Y-m-d",strtotime($post_data["out_date"]));
            $out_time          = $post_data["out_time"];
			$total_time        = $post_data["total_time"];
			$day_type          = $post_data["day_type"];
			$in_date_time      = date('Y-m-d H:i', strtotime($in_date.' '.$in_time));
            $out_date_time     = date('Y-m-d H:i', strtotime($out_date.' '.$out_time));
		}
		
		if($request_type === 1 || $request_type === 3 || $request_type === 7){
			$leave_onduty_entry_arr  = $this->build_common_valid_array(); //function for build array (leave_entry,onduty_entry table)
			if($from_date < $to_date){
				$a = new DateTime($from_date);
				$b = new DateTime($to_date);
				$str_date = $a->format('Y-m-d');
				$finish_date = $b->format('Y-m-d');
				$start_date = clone $a; // Use clone to avoid modifying the original $a object
				$end_date = clone $b;		
				// Create a DatePeriod object to iterate over the range of dates
				$date_interval = new DateInterval('P1D'); // 1 day interval
				$date_range = new DatePeriod($start_date, $date_interval, $end_date);
		
				foreach ($date_range as $date) {
					$chk_date = $date->format('Y-m-d');
					if ($chk_date !== $str_date && $chk_date !== $finish_date) {
						$date_count_val = $leave_onduty_entry_arr[$employee_code][$chk_date];
						if ($date_count_val) {
							$multiple_date_arr[$employee_code] = [$chk_date];
						}
					}
				}
			}
			$from_check_val          = $leave_onduty_entry_arr[$employee_code][$from_date][$from_date_type];
			$to_check_val            = $leave_onduty_entry_arr[$employee_code][$to_date][$to_date_type];
			$date_count_val          = $leave_onduty_entry_arr[$employee_code][$from_date][1] + $leave_onduty_entry_arr[$employee_code][$from_date][2] + $leave_onduty_entry_arr[$employee_code][$from_date][3];
			// Iterate through the dates and add them to the array
			$mp_entry_qry            = 'select count(*)as mp_exist_count from cw_manual_punch_entry where employee_code="'.$employee_code.'" and shift_date="'.$shift_date.'" and day_type ="'.$day_type.'" and leave_status in(1,2)';
			$mp_entry_info         = $this->runQuery($mp_entry_qry);
			$mp_entry_result       = $this->result_array($mp_entry_info);
			$mp_exist_count        = $mp_entry_result[0]['mp_exist_count'];
			if($from_check_val || $to_check_val){
				echo $this->returnResult(FALSE, 'Leave or Onduty Already Applied For this Date type...!', [], []);
				exit(0);
			}else
			if((int)$date_count_val >= 1){
				echo $this->returnResult(FALSE, 'Leave or Onduty Already Applied For this Date...!', [], []);
				exit(0);
			}else
			if((int)$mp_exist_count > 0){
				echo $this->returnResult(FALSE, 'Manual punch Already Exist in this data...!', [], []);
				exit(0);
			}else
			if($multiple_date_arr){
				echo $this->returnResult(FALSE, 'Leave or Onduty Already applied for inbetween date...!', [], []);
				exit(0);
			}else{
				return true;
			}
		}else{
			return true;
		}
	}

	//function for build array(leave entry table and onduty entry table)
	public function build_common_valid_array(){
		//TIME OF SETTING BASED SALARY START AND END DATE DETAILS
		$last_payroll_month   = 'select max(date_format(str_to_date(CONCAT("01-", transactions_month), "%d-%m-%Y") , "%Y-%m")) as max_month from cw_transactions where trans_status = 1';
		$last_payroll_info    = $this->runQuery($last_payroll_month);
		$last_payroll_rslt    = $this->result($last_payroll_info);
		$last_pay_month       = $last_payroll_rslt[0]->max_month;
		
		$nxt_month            = date("d-m-Y", strtotime($last_pay_month."-01"));
		//GET SALARY FROM DATE
		$month_day_result     = $this->tos_day_qry_fun("3");
		$day_start            = $month_day_result[0]->day_start;
		$day_end              = $month_day_result[0]->day_end;
		$salary_start_date    = date("Y-m",strtotime($nxt_month))."-".$day_start;
		//Check Leave Entry Exist
		$sel_leave_entry_qry  = 'select employee_code,leave_date,leave_count,date_type from cw_leave_entry where leave_date >= "'.$salary_start_date.'" and trans_status = 1 and leave_status in(1,2)';
		$leave_entry_info     = $this->runQuery($sel_leave_entry_qry);
		$leave_entry_result   = $this->result_array($leave_entry_info);
		foreach($leave_entry_result as $arr){
			$leave_entry_arr[$arr['employee_code']][$arr['leave_date']][$arr['date_type']]=$arr['leave_count'];
		}
		//check Onduty Entry Exist 
		$sel_onduty_entry_qry  ='select employee_code,on_duty_date,date_type,on_duty_count from cw_on_duty_entry where on_duty_date >= "'.$salary_start_date.'" and trans_status = 1 and on_duty_status in (1,2)';
		$sel_onduty_info       = $this->runQuery($sel_onduty_entry_qry);
		$sel_onduty_result     = $this->result_array($sel_onduty_info);
		foreach($sel_onduty_result as $arr){
			$onduty_entry_arr[$arr['employee_code']][$arr['on_duty_date']][$arr['date_type']]=$arr['on_duty_count'];
		}
		$result = array();
		// Merge onduty_entry_arr into result
		foreach ($onduty_entry_arr as $key => $onduty_dates){
			foreach ($onduty_dates as $date => $onduty_values){
				if (isset($result[$key][$date])) {
					// If the key and date exist in both arrays, sum the values
					foreach ($onduty_values as $subkey => $subvalue) {
						$result[$key][$date][$subkey] += $subvalue;
					}
				}else{
					// If the key and date do not exist in $result, copy values from $onduty_entry_arr
					$result[$key][$date] = $onduty_values;
				}
			}
		}			
		// Merge leave_entry_arr into result
		foreach ($leave_entry_arr as $key => $leave_dates) {
			foreach ($leave_dates as $date => $leave_values) {
				if (isset($result[$key][$date])) {
					// If the key and date exist in both arrays, sum the values
					foreach ($leave_values as $subkey => $subvalue) {
						$result[$key][$date][$subkey] += $subvalue;
					}
				} else {
					// If the key and date do not exist in $result, copy values from $leave_entry_arr
					$result[$key][$date] = $leave_values;
				}
			}
		}
		return $result;		
	}

	//Shift Change Request Check for permission and manual punch and business trip
	public function check_exist_shift_sts($component_value,$employee_code,$shift_date){
		$leave_financial_info = $this->get_leave_financial_details();
		$financial_year_id    = $leave_financial_info[0]->prime_leave_financial_year_id;	

		//Check pending shift change exist from request  
		$shift_request_qry    = 'SELECT count(cw_request.prime_request_id) as count FROM cw_request WHERE cw_request.employee_code = "'.$employee_code.'" and cw_request.shift_date = "'.$shift_date.'" and cw_request.request_type = "6" and cw_request.leave_status in (1) and cw_request.financial_setting_id = "'.$financial_year_id.'" and cw_request.trans_status = 1';
		// cw_request.leave_status in (1,2)
		$shift_request_info   = $this->runQuery($shift_request_qry);
		$shift_request_rslt   = $this->result($shift_request_info);
		$shift_count          = (int)$shift_request_rslt[0]->count;

		if($shift_count){
			return false;
		}else{
			return true;
		}
	}
	# CANCEL REQUEST
	public function cancelRequest($json){
		$validate_jwt          = $this->validate_jwt();
		$logged_id             = $validate_jwt->code;
		$prime_id              = $json->prime_id;
		//$cancellation_request  = $json->cancellation_request;
		$created_on            = date("Y-m-d H:i:s");
		$leave_financial_info  = $this->get_leave_financial_details();
		$prime_financial_id    = $leave_financial_info[0]->prime_leave_financial_year_id;
		// ,cw_request.employee_code,cw_request.request_type,cw_request.leave_type,cw_request.no_of_days
		$exist_request_qry     = 'SELECT cw_request.*,count(prime_request_id) as count,cw_employees.role FROM cw_request inner join cw_employees on cw_employees.employee_code = cw_request.employee_code WHERE prime_request_id = "'.$prime_id.'"  and financial_setting_id = "'.$prime_financial_id.'" and first_approval_leave_status = 1 and second_approval_leave_status = 1 and cancellation_request = 2 and cw_employees.trans_status = 1 and cw_request.trans_status = 1';
		$exist_request_info    = $this->runQuery($exist_request_qry);
		$exist_request_rslt    = $this->result($exist_request_info);
		$exist_count           = (int)$exist_request_rslt[0]->count;
		$employee_code         = $exist_request_rslt[0]->employee_code;
		$request_type          = (int)$exist_request_rslt[0]->request_type;
		$leave_type            = (int)$exist_request_rslt[0]->leave_type;
		$no_of_days            = $exist_request_rslt[0]->no_of_days;
		$from_date             = $exist_request_rslt[0]->from_date;
		$to_date               = $exist_request_rslt[0]->to_date;

		//request type based to get a request date for check a salary start date
		if($request_type === 1 || $request_type === 3 || $request_type === 8){
			$request_date      = date("Y-m-d",strtotime($exist_request_rslt[0]->from_date));
		}else
		if($request_type === 4 || $request_type === 5){
			$request_date      = date("Y-m-d",strtotime($exist_request_rslt[0]->permission_date));
		}else
		if($request_type === 7 || $request_type === 6){
			$request_date      = date("Y-m-d",strtotime($exist_request_rslt[0]->shift_date));
		}
		//To month day query for get salary process month details
        $month_day_info        = $this->tos_day_info($employee_code,"3"); // 3 => Leave Entry
		if(count($month_day_info ?? [])){
			$salary_start_date    =  date("Y-m-d",strtotime($month_day_info['salary_start_date']));
			if($exist_count === 1){
				if($salary_start_date > $request_date){
					return $this->returnResult(FALSE, 'Past Payroll Transaction Entry should not Cancel.!', [], []);
				}else{
					//IF REQUEST TYPE WAS LEAVE THEN UPDATE LEAVE BALANCE COUNT TO LEAVE OPENING TABLE
					
					if($request_type === 1){
						//select query for get a leave name and leave opening
						$leave_name_query     = 'SELECT lower(leave_name) as leave_name,leave_opening FROM cw_leave_creation WHERE trans_status = 1 and prime_leave_creation_id = "'.$leave_type.'"';
						$leave_name_info      = $this->runQuery($leave_name_query);						
						$leave_name_rslt      = $this->result($leave_name_info);
						$leave_opening        = (int)$leave_name_rslt[0]->leave_opening;
						$leave_name           = $leave_name_rslt[0]->leave_name;

						if($leave_opening === 1){
							//SELECT QUERY FOR GET A EMPLOYEE LEAVE BALANCE COUNT FROM LEAVE OPENING
							$leave_count_qry     = 'SELECT '.$leave_name.' as leave_count,pending_'.$leave_name.' as pending_count FROM cw_leave_opening WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and cw_leave_opening.financial_setting_id = "'.$prime_financial_id.'" and cw_leave_opening.trans_status = 1';

							$leave_count_info    = $this->runQuery($leave_count_qry);						
							$leave_count_rslt    = $this->result($leave_count_info);
							$leave_count         = $leave_count_rslt[0]->leave_count;
							$pending_count       = $leave_count_rslt[0]->pending_count;
							$fin_pending_count   = $pending_count - $no_of_days;

							//TO UPDATE A LEAVAE BALANCE COUNT TO LEAVE OPENING TABLE FOR THAT EMPLOYEE
							$leave_count_upd_qry = 'UPDATE cw_leave_opening SET pending_'.$leave_name.' = "'.$fin_pending_count.'",trans_updated_by = "'.$logged_id.'",trans_updated_date = "'.$created_on.'" WHERE cw_leave_opening.employee_code = "'.$employee_code.'" and cw_leave_opening.financial_setting_id = "'.$prime_financial_id.'" and cw_leave_opening.trans_status = 1';
							$this->runQuery($leave_count_upd_qry);	
						}
					}
					//request delete qry
					$request_update_qry   = 'UPDATE cw_request SET trans_status = "0",trans_deleted_by = "'.$logged_id .'",trans_deleted_date = "'.$created_on.'" WHERE prime_request_id = "'. $prime_id .'"';
					$this->runQuery($request_update_qry);	

					//approval delete qry
					$approval_update_qry  = 'UPDATE cw_approval SET trans_status = "0",trans_deleted_by = "'.$logged_id .'",trans_deleted_date = "'.$created_on.'" WHERE cw_approval.prime_request_id = "'. $prime_id .'"';
					$this->runQuery($approval_update_qry);
					//FOR SHIFT CHANGE
					if($request_type === 6){
						return $this->returnResult(TRUE, 'Successfully Deleted.!', [], []);
					}else{
						//REQUEST BASED ARRAY CREATION FOR UPDATE A REQUEST
						$tbl_arr              = array(1=>'cw_leave_entry',3=>'cw_on_duty_entry',4=>'cw_permission_entry',5=>'cw_permission_entry',7=>'cw_manual_punch_entry',8=>'cw_on_duty_entry');
				
						//delete qry process
						$request_entry_upd_qry  = 'UPDATE '.$tbl_arr[$request_type].' SET trans_status = "0",trans_deleted_by = "'.$logged_id .'",trans_deleted_date = "'.$created_on.'" WHERE '.$tbl_arr[$request_type].'.prime_request_id = "'. $prime_id .'"';
						$this->runQuery($request_entry_upd_qry);

						if($from_date && $to_date){
						//FOR TIME ENTRY ACTION STATUS CHECK AND UPDATE 
							$time_entry_qry      = 'select att_date,action_status from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date between ("'.$from_date.'") and ("'.$to_date.'") and cw_time_entry.trans_status = 1';
							$time_entry_info     = $this->runQuery($time_entry_qry);						
							$time_entry_result   = $this->result_array($time_entry_info);
							$time_entry_arr      = array();
							foreach($time_entry_result as $time_val){
								$time_att_date   = $time_val['att_date']; 
								//PUSH TO ACTION STATUS (ACTION TAKEN) ONLY  
								// if($time_action_status === 2){
									$time_entry_arr[$time_att_date]  = $time_att_date;
								// }
							}
							$att_date_where      = implode('","',$time_entry_arr ?? []);
							if($att_date_where){
								//FOR TIME ENTRY ACTION STATUS UPDATE 
								$upd_time_entry = 'UPDATE cw_time_entry SET action_status = "1",trans_updated_by = "'.$logged_id.'", trans_updated_date = "'.$created_on.'" WHERE cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date in ("'.$att_date_where.'") and cw_time_entry.trans_status = 1';
								$this->runQuery($upd_time_entry);
							}
						}
						return $this->returnResult(TRUE, 'Successfully Cancelled.!', [], []);
					}
				}		
			}else{
				return $this->returnResult(TRUE, 'Request Data Not Exist or Already Cancelled.!', [], []);
			}
		}else{
			return $this->returnResult(TRUE, 'Please Set Month Day for this Category.!', [], []);
		}
	}
	//FUNCTION FOR USING TO MANAGE MODULE EDIT VIEW AND CANCEL BUTTON VALIDATION ARRAY GET
	public function request_data_arr($prime_financial_id){
		$leave_status_query    = 'SELECT prime_request_id,first_approval_leave_status as first_leave_status,second_approval_leave_status as second_leave_status,leave_status,cancellation_request,request_type FROM cw_request WHERE cw_request.trans_status = 1 and financial_setting_id = "'.$prime_financial_id.'"';
		$leave_status_info     = $this->runQuery($leave_status_query);
		$leave_status_result   = $this->result_array($leave_status_info);
		$rslt                  = array();
		$leave_status_arr      = array();
		$leave_cancel_arr      = array();
		$emp_cancel_arr        = array();
		foreach($leave_status_result as $arr){
			$request_id                    = $arr['prime_request_id'];
			$leave_status                  = $arr['leave_status'];
			$cancel_request                = $arr['cancellation_request'];
			$leave_status_arr[$request_id] = $leave_status;
			$leave_cancel_arr[$request_id] = $cancel_request;
			$emp_cancel_arr[$request_id]   = $arr;
		}
		//ALL ARRAYS ADD TO FINAL ARRAY
		$rslt['leave_status_arr']   = $leave_status_arr;
		$rslt['leave_cancel_arr']   = $leave_cancel_arr;
		$rslt['emp_cancel_arr']     = $emp_cancel_arr;
		return $rslt;
	}

	//this condition check for other request exist
	public function check_exist_request_sts($component_value,$employee_code,$shift_date){
		$leave_financial_info = $this->get_leave_financial_details();
		$financial_year_id    = $leave_financial_info[0]->prime_leave_financial_year_id;	
		$permission_entry_qry  = 'SELECT count(cw_permission_entry.prime_permission_entry_id) as count FROM cw_permission_entry WHERE cw_permission_entry.employee_code = "'.$employee_code.'" and cw_permission_entry.permission_date = "'.$shift_date.'" and cw_permission_entry.leave_status in (1,2) and financial_setting_id = "'.$financial_year_id.'" and trans_status = 1';
		$permission_entry_info = $this->runQuery($permission_entry_qry);
		$permission_entry_rslt = $this->result($permission_entry_info);
		$permission_count      = (int)$permission_entry_rslt[0]->count;
		
		//check exist from manual punch entry
		$man_punch_check_qry   = 'SELECT COUNT(cw_manual_punch_entry.prime_manual_punch_entry_id) as count from cw_manual_punch_entry where cw_manual_punch_entry.employee_code = "'.$employee_code.'" and cw_manual_punch_entry.shift_date = "'.$shift_date.'" and cw_manual_punch_entry.leave_status in (1,2) and financial_setting_id = "'.$financial_year_id.'" and trans_status = 1';
		$man_punch_check_info  = $this->runQuery($man_punch_check_qry);
		$man_punch_check_rslt  = $this->result($man_punch_check_info);
		$mp_check_count        = (int)$man_punch_check_rslt[0]->count;

		//check exist from overtime entry 
		$overtime_check_qry   = 'SELECT COUNT(cw_overtime_entry.prime_overtime_entry_id) as count from cw_overtime_entry where cw_overtime_entry.employee_code = "'.$employee_code.'" and cw_overtime_entry.entry_date = "'.$shift_date.'" and cw_overtime_entry.approval_status in (1,2) and financial_setting_id = "'.$financial_year_id.'" and trans_status = 1';
		$overtime_check_info  = $this->runQuery($overtime_check_qry);
		$overtime_check_rslt  = $this->result($overtime_check_info);
		$overtime_count       = (int)$overtime_check_rslt[0]->count;
		//|| $time_count
		if($permission_count || $mp_check_count || $overtime_count){
			return false;
		}else{
			return true;
		}
	}

	public function check_coff_late($employee_code,$from_date){
		//get Category from employees
		$get_emp_query    = 'SELECT role from cw_employees WHERE employee_code = "'. $employee_code .'" and trans_status = 1';
		$get_emp_info     = $this->runQuery($get_emp_query);
		$get_emp_rlst     = $this->result($get_emp_info);
		$emp_category     = $get_emp_rlst[0]->role;
		$get_coff_result = $this->get_coff_settings($employee_code,$emp_category);

		$halfday_min     = $get_coff_result[0]->halfday_min;
		$ot_activated    = $get_coff_result[0]->ot_activated;
		$halfday_hours   = $this->hours_mins_cal($halfday_min);
		$coff_late_date  =  date("Y-m-d",strtotime("-1 day",strtotime($from_date)));
		$perm_entry_qry  = 'select count(prime_permission_entry_id) as count from cw_permission_entry where trans_status = 1 and employee_code = "'.$employee_code.'" and permission_date = "'.$from_date.'"';
		$perm_info   = $this->runQuery($perm_entry_qry);
		$perm_result = $this->result($perm_info);
		$perm_count  = (int)$perm_result[0]->count;
		if($perm_count > 0){
			echo $this->returnResult(FALSE, 'Already Coff Late Permission Taken.!', [], []);
			exit(0);
		}
		$time_entry_qry  = 'select coff_hours,employee_code,att_date from cw_time_entry where trans_status = 1 and cw_time_entry.employee_code = "'.$employee_code.'" and att_date = "'.$coff_late_date.'"';
		$time_entry_info   = $this->runQuery($time_entry_qry);
		$time_entry_result = $this->result_array($time_entry_info);
		$coff_hours = $time_entry_result[0]['coff_hours'];
		if((int)$halfday_min < (int)$coff_hours){
			echo $this->returnResult(FALSE, "Coff Late Hours should be greater than or equal to $halfday_hours", [], []);
			exit(0);
		}else{
			return true;
		}
	}

	//Check Coff exist for the leave date
	public function check_coff_exist($employee_code,$prime_financial_id,$from_date){
		//and financial_setting_id = "'.$prime_financial_id.'" Commented by BSK
		$coff_entry_qry      = 'select SUM(balance_count) as coff_count from cw_coff_entry where employee_code = "'.$employee_code.'" and credited_date <= "'.$from_date.'" and trans_status = 1 and coff_status = 1';
			$coff_entry_info     = $this->runQuery($coff_entry_qry);
			$coff_entry_result   = $this->result($coff_entry_info);
			$coff_count          = $coff_entry_result[0]->coff_count;
			if(!$coff_count){
				$coff_count = 0;
			}
			return $coff_count;
	}	

	//FUNCTION FOR GET SHIFT NAME FOR LEAVE AND OT REQUEST DATE
	public function other_request_exist($employee_code,$financial_year_id,$from_date,$to_date,$from_date_type,$to_date_type){
		$between_date_from   = '';
		$between_date_to     = '';
		//------------- FULL DAY TYPE BASED DATE ONLY EXIST COUNT CHECK ----------------
		//CHECK FROM DATE AND TO DATE WAS ONE DATE DIFFERENCE
		$check_diff_date  = date("Y-m-d",strtotime("+1 days",strtotime($from_date)));
		//MORE THAN ONE DAY DIFFERENCE
		if($from_date !== $to_date && $to_date !== $check_diff_date){
			// FULL DAY TYPE ONLY EXIST CHECK
			if($from_date_type === 1){
				$between_date_from  = $from_date;
			}else{
				$between_date_from  = $check_diff_date;
			}
			// FULL DAY TYPE ONLY EXIST CHECK
			if($to_date_type === 1){
				$between_date_to  = $to_date;
			}else{
				$between_date_to  = date("Y-m-d",strtotime("-1 days",strtotime($to_date)));
			}
		}else{
			//FOR FULL DAY TYPE ONLY CHECK
			if($from_date_type === 1){
				$between_date_from    = $from_date;
			}
			if($from_date !== $to_date){
				//FOR FULL DAY TYPE ONLY CHECK
				if($to_date_type === 1){
					$between_date_to  = $to_date;
				}
			}
		}
		//FROM AND TO DATE WHERE COND BUILD
		$date_where_cond       = '';
		if($between_date_from && $between_date_to){
			$date_where_cond   = ' and cw_permission_entry.permission_date >= "'.$between_date_from.'" and cw_permission_entry.permission_date <= "'.$between_date_to.'"';
		}else
		if($between_date_from){
			$date_where_cond   = ' and cw_permission_entry.permission_date = "'.$between_date_from.'"';
		}else
		if($between_date_to){
			$date_where_cond   = ' and cw_permission_entry.permission_date = "'.$between_date_to.'"';
		}
		if(!$date_where_cond){
			return true;
		}else{
			//check exist from permission entry 
			$permission_entry_qry  = 'SELECT count(cw_permission_entry.prime_permission_entry_id) as count FROM cw_permission_entry WHERE cw_permission_entry.employee_code = "'.$employee_code.'"'.$date_where_cond.' and cw_permission_entry.leave_status in (1,2) and financial_setting_id = "'.$financial_year_id.'" and trans_status = 1';
			$permission_entry_info = $this->runQuery($permission_entry_qry);
			$permission_entry_rslt = $this->result($permission_entry_info);
			$permission_count      = (int)$permission_entry_rslt[0]->count;

			if($permission_count){
				echo $this->returnResult(FALSE, 'Already Permission Request Exist.!', [], []);
				exit(0);
			}else{
				return true;
			}
		}
	}

	public function get_coff_settings($employee_code,$category){
		$company_info       = $this->company_info();
		$coff_based_on      = $company_info[0]->coff_based_on; //Get from company info module.
		if(!$coff_based_on){
			echo $this->returnResult(FALSE, 'Please set coff based on input in timeoffice setting..', [], []);
			exit(0);
		}
		$coff_check_qry = "";
		if($coff_based_on !== 'role' && $coff_based_on !== '0'){
			$emp_pick_arr   = $this->get_emp_data($employee_code);
			$coff_check_val = $emp_pick_arr[$employee_code][$coff_based_on];
			if(!$coff_check_val){
				echo $this->returnResult(FALSE, 'Check input not exist for this Employee..!', [], []);
				exit(0);
			}
			$coff_check_qry = ' and FIND_IN_SET('.$coff_check_val.', cw_coff_settings.check_input)';
		}
		$check_inp_qry     = 'SELECT * from cw_coff_settings where FIND_IN_SET('.$category.', cw_coff_settings.category) '.$coff_check_qry;
		$check_inp_info    = $this->runQuery($check_inp_qry);
		$check_inp_result  = $this->result($check_inp_info);
		return $check_inp_result;
	}

	//function for get hours and minutes in two degits format
	public function hours_mins_cal($hrs_mins){
		$get_hrs            = floor($hrs_mins / 60);
		$get_mins           = ($hrs_mins -   floor($hrs_mins / 60) * 60);
		//ternary operator using for get a hour and minutes with two digits format
		$get_hrs_format     = (strlen((string)$get_hrs) === 1) ? ('0'.$get_hrs) : ($get_hrs);
		$get_mins_format    = (strlen((string)$get_mins) === 1) ? ('0'.$get_mins) : ($get_mins);
		
		$total_hrs_mins     = $get_hrs_format.':'.$get_mins_format;
		return $total_hrs_mins;
	} 

	//PROCESS MONTH WISE SALARY START DATE AND END DATE GET
	public function tos_sal_strt_end_info($process_parameter,$process_month){
		$month_day_result      = $this->tos_day_qry_fun((int)$process_parameter);
		if($month_day_result){
			$day_conditions    = $month_day_result[0]->day_conditions;
			$day_start         = $month_day_result[0]->day_start;
			$day_end           = $month_day_result[0]->day_end;
			if((int)$day_conditions === 3){
				$sal_start         = $day_start;
				//For Current month between days increment
				$date              = new DateTime("01-$process_month 00:00:00");
				$date->modify('-1 month');
				$salary_start_date = $date->format("$sal_start-m-Y");	
				$salary_end_date   = date('d-m-Y',strtotime("$day_end-".$process_month));
			}else{
				$sal_start         = '01';
				if((int)$day_conditions === 2){
					$day_end           = date('t',strtotime("01-".$process_month));
				}
				$date              = new DateTime("01-$process_month 00:00:00");
				$salary_start_date = $date->format("$sal_start-m-Y");	
				$salary_end_date   = date("d-m-Y",strtotime($day_end."-".$process_month));
			}
			$sal_start_end_arr     = array("salary_start_date" => $salary_start_date,"salary_end_date" => $salary_end_date);
			return $sal_start_end_arr;
		}
	}

	//TIME ENTRY COFF HOURS GET
	public function time_entry_coff_hrs($prime_financial_id,$employee_code,$coff_permission_date){
		$time_entry_qry      = 'select coff_hours from cw_time_entry where cw_time_entry.employee_code = "'.$employee_code.'" and cw_time_entry.att_date = "'.$coff_permission_date.'" and cw_time_entry.trans_status = 1';
		$time_entry_info     = $this->runQuery($time_entry_qry);
		$time_entry_rslt     = $this->result_array($time_entry_info);
		return $time_entry_rslt;
	}

	//FUNCTION FOR PERMISSION DATE CHECK EXIST FROM LEAVE AND OD ENTRY
	public function check_exist_leave_od($component_value,$financial_year_id,$employee_code,$check_date){
		//Check Exist from Leave Entry (only for full day type)
		$leave_entry_qry  = 'SELECT count(cw_leave_entry.prime_leave_entry_id) as count FROM cw_leave_entry WHERE cw_leave_entry.employee_code = "'.$employee_code.'" and cw_leave_entry.leave_date = "'.$check_date.'" and cw_leave_entry.leave_status in (1,2) and cw_leave_entry.date_type in (1) and cw_leave_entry.financial_setting_id = "'.$financial_year_id.'" and cw_leave_entry.trans_status = 1';
		$leave_entry_info = $this->runQuery($leave_entry_qry);
		$leave_entry_rslt = $this->result($leave_entry_info);
		$leave_count      = (int)$leave_entry_rslt[0]->count;

		if($leave_count){
			// echo json_encode(array('success' => false, 'message' => "Already Leave Request Exist.! Please Cancel the Previous Transaction and try Again.!"));
			// exit(0);
			return false;
		}else{
			//Check Exist from OD Entry (only for full day type)
			$od_entry_qry  = 'SELECT count(cw_on_duty_entry.prime_on_duty_entry_id) as count FROM cw_on_duty_entry WHERE cw_on_duty_entry.employee_code = "'.$employee_code.'" and cw_on_duty_entry.on_duty_date = "'.$check_date.'" and cw_on_duty_entry.financial_setting_id = "'.$financial_year_id.'" and cw_on_duty_entry.on_duty_status in (1,2) and cw_on_duty_entry.date_type in (1) and cw_on_duty_entry.trans_status = 1';
			$od_entry_info = $this->runQuery($od_entry_qry);
			$od_entry_rslt = $this->result($od_entry_info);
			$od_count      = (int)$od_entry_rslt[0]->count;
			if($od_count){
				return false;
			}else{
				return true;
			}
		}
	}

	# FROM MONTH TO MONTH VALIDATION [MS 04-12-2024]
	public function fromToMonthValidation($fromMonth,$toMonth,$action){
		if($action !== 'date'){
			$fromMonth  = strtotime('01-'.$fromMonth);
			$toMonth    = strtotime('31-'.$toMonth);
		}
		if($toMonth < $fromMonth){
			return 1;
		}
	}

	# FROM DATE TYPE TO DATE TYPE VALIDATION
	public function fromToType_validation($from_date,$to_date,$from_date_type,$to_date_type){
		if($from_date === $to_date){
			if($from_date_type !== $to_date_type){			
				return array("succes" => false , 'msg' => "Please Check Your From Date and To Date Type..");
			}	
		}else
		if($from_date !== $to_date){
			if((int)$from_date_type === 2){
				return array("succes" => false , 'msg' => "Please Check Your From Date Type..");
			}else
			if((int)$to_date_type === 3){
				return array("succes" => false , 'msg' => "Please Check Your To Date Type..");
			}
		}	
	}
	//FUNCTION FOR MAIL OTP
	public function send_otp_mail($login_email,$login_otp){
		if($login_email){
			$config_query  = 'SELECT smtp_server,sender_name,bcc,port_no,sender_email,mail_username,mail_password FROM cw_mail_configurations WHERE trans_status = 1';
			$config_info   =  $this->runQuery($config_query);
			$config_result = $this->result($config_info);
			$smtp_server   = $config_result[0]->smtp_server;
			$sender_name   = $config_result[0]->sender_name;
			$port_no       = $config_result[0]->port_no;
			$sender_email  = $config_result[0]->sender_email;
			$username      = $config_result[0]->mail_username;
			$password      = $config_result[0]->mail_password;			
			try{
				$mail             = new PHPMailer();
				// $mail->SMTPDebug  = 1;
				$mail->IsSMTP();
				$mail->Host       = $smtp_server; // Your SMTP PArameter
				$mail->Port       = $port_no; // Your Outgoing Port
				$mail->SMTPAuth   = true; // This Must Be True
				$mail->Username   = $username; // Your Email Address
				$mail->Password   = $password; // Your Password
				$mail->SMTPSecure = 'tls'; // Check Your Server's Connections for TLS or SSL
				$mail->From       = $sender_email;
				$mail->FromName   = $sender_name;				
				$mail->AddAddress($login_email);
				// $mail->AddAddress("sathish@cafsinfotech.in");
				$mail->IsHTML(true);
				$mail->Subject    = 'Smart Hrms (OTP)';
				$message_body     = date("d-M-Y H:i:s").'<p> Your One Time Password(OTP) : <b style = "color:blue;">'.$login_otp.'</b>. For Verify Your Login From </p>
									<p>smart hrms</p>';
				$mail->Body       = $message_body;
				$mail             = $mail->Send();
				if($mail){
					$status = 1;
				}else{
					$status = 0;
				}
			}catch(phpmailerException $e){
				$status = 0;
				return array('success'=>false,'message'=>"Mail Not Sent");
			}catch(Exception $e){
				$status = 0;
				return array('success'=>false,'message'=>"Mail Not Sent");
			}
			if(!$status){
				return array('success'=>false,'message'=>"Mail Not Sent");
			}else{
				return 1;
			}
		}else{
			return array('success'=>false,'message'=>"Email ID Not Exist.. Please Contact HR..!!");
		}
	} 

	# GENERAL SETTING QUERY FUNCTION
    public function general_setting_info($entry_parameter){
        $gen_qry  = 'SELECT * FROM cw_general_setting WHERE trans_status = 1 AND  cw_general_setting.entry_parameter_type = "'.$entry_parameter.'"';
        $gen_info = $this->runQuery($gen_qry);
        $gen_rslt = $this->result($gen_info);
        return $gen_rslt;
    }

	# EMP RSLT FOR CREATE TOKEN 
	public function emp_rslt($code , $pass){
		if($pass){
			$enc_pass = $this->cryptoEncrypt(md5($pass));
			$pass_qry = ' AND password = "'.$enc_pass.'"';
		} 
		$emp_qry  = 'SELECT prime_employees_id,employee_code,emp_name,trans_status,role,device_code,user_right,first_time_login,login_with_otp,mobile_checkin,first_level_approval,second_level_approval,mobile_number,company_email_id,imei_no,loc_allow FROM cw_employees WHERE trans_status = 1 AND termination_status = 0 AND employee_code = "'.$code.'" '.$pass_qry;
		// echo $emp_qry; die;
        $emp_info = $this->runQuery($emp_qry);
        $emp_rslt = $this->result($emp_info);
		return $emp_rslt;
	}

	# IMEI VALIDATION
	function validate_imei($imei,$code){
		$imei_qry  = 'SELECT count(employee_code) as count FROM cw_employees WHERE imei_no = "'.$imei.'" AND employee_code <> "'.$code.'"';
		$imei_info = $this->runQuery($imei_qry);
        $imei_rslt = $this->result($imei_info);
		return $imei_rslt[0]->count;
	}
	#USED FOR PASSWORD ONEWAY ENCRYPTION
	public function cryptoEncrypt($data){
		try {
			// For Password Encryption
			$hash1     = hash('sha512', $data);
			$hash2     = hash('sha1', $hash1);
			$Hash3     = hash('haval160,4', $hash2); 
			$Hash4     = hash('haval160,5', $Hash3); 
			// Generate the HMAC hash
			$finalhash = hash_hmac('sha256', $Hash4, $this->enckey);		
			return $finalhash;
		} catch (Exception $e) {
			// Log the error or handle it as needed
			error_log("Encryption Error: " . $e->getMessage()); // Log the error for debugging
			return false;
		}
	}

	# HOLIDAY 
	public function holiday_status($code){
		$tos_day_info   = $this->tos_day_info($code,"4");
		$starting_date  = $tos_day_info['starting_date'];
		$ending_date    = $tos_day_info['ending_date'];
		$holiday_qry    = 'SELECT label_name,components FROM cw_general_setting INNER JOIN cw_form_setting ON cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 2 AND cw_general_setting.trans_status = 1';
		$holiday_info   = $this->runQuery($holiday_qry);
		$holiday_rslt   = $this->result($holiday_info);
		$hol_label_name = $holiday_rslt[0]->label_name;
		$emp_pick_arr   = $this->get_emp_data($code);
		$holid_comp_val = $emp_pick_arr[$code][$hol_label_name];
		$holiday_qry    = 'SELECT cw_holiday_entry_holiday_data.* FROM cw_holiday_entry INNER JOIN cw_holiday_entry_holiday_data ON cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id WHERE FIND_IN_SET("'.$holid_comp_val.'", cw_holiday_entry_holiday_data.component_value) AND cw_holiday_entry.holiday_year BETWEEN "'.$starting_date.'" AND "'.$ending_date.'" AND cw_holiday_entry.trans_status = 1 AND cw_holiday_entry_holiday_data.trans_status = 1';
		$holiday_info   = $this->runQuery($holiday_qry);
		$holiday_result = $this->result($holiday_info);
		if($holiday_info){
			if(count($holiday_result ?? []) > 0){
				$holiday_arr = array();
				foreach($holiday_result as $arr){
					$holiday_arr[$arr->holiday_date] = $arr;
				}
				return $holiday_arr;
			}
		}
	}

	# SALARY DATE 
	public function salaryDate($json){
		$validate_jwt        = $this->validate_jwt(); # JWT TOKEN
		$user_role           = $validate_jwt->user_right;
		$code                = $json->code;	
		$company_info        = $this->company_info();
		$max_allow_date      = (int)$company_info[0]->max_allow_date;
		$max_date_based      = $company_info[0]->max_date_based;

		$tos_day_info        = $this->tos_day_info($code,"4");
		if(!$tos_day_info){
			return $this->returnResult(False, 'Please Set Month Day for this Category...', [], []);
		}
		foreach($tos_day_info as $key => $val){
			$tos_day_info[$key]  = date('Y-m-d',strtotime($val));
		}

		$salary_start_date = $tos_day_info['salary_start_date'];
		$based_on      = is_array($max_date_based) ? $max_date_based : explode(',', $max_date_based);
		if(in_array($user_role, $based_on)){
			$allowed_date = date('Y-m-d', strtotime("-{$max_allow_date} days"));
			//ALLOWED DATE WAS BECOME ATARTING DATE
			if($allowed_date > $salary_start_date){
				$salary_start_date = $allowed_date;
			}
		}

		// UPDATE START DATE
		$tos_day_info['salary_start_date'] = $salary_start_date;

		return $this->returnResult(TRUE, 'Success', $tos_day_info, []);
	}

	# GET HOLIDAY LIST
	public function holidayList($json){
		$this->validate_jwt(); # JWT TOKEN
        $code           = $json->code;
		$tos_day_info   = $this->tos_day_info($code,"4");
		$starting_date  = $tos_day_info['starting_date'];
		$ending_date    = $tos_day_info['ending_date'];

		$holiday_qry    = 'SELECT label_name,components FROM cw_general_setting INNER JOIN cw_form_setting ON cw_form_setting.prime_form_id = cw_general_setting.components WHERE entry_parameter_type = 2 AND cw_general_setting.trans_status = 1';
		$holiday_info   = $this->runQuery($holiday_qry);
		$holiday_rslt   = $this->result($holiday_info);
		$hol_label_name = $holiday_rslt[0]->label_name;
		$emp_pick_arr   = $this->get_emp_data($code);
		$holid_comp_val = $emp_pick_arr[$code][$hol_label_name];
		$holiday_qry    = 'SELECT cw_holiday_entry_holiday_data.* FROM cw_holiday_entry INNER JOIN cw_holiday_entry_holiday_data ON cw_holiday_entry_holiday_data.prime_holiday_entry_id = cw_holiday_entry.prime_holiday_entry_id WHERE FIND_IN_SET("'.$holid_comp_val.'", cw_holiday_entry_holiday_data.component_value) AND cw_holiday_entry_holiday_data.holiday_date BETWEEN "'.$starting_date.'" AND "'.$ending_date.'" AND cw_holiday_entry.trans_status = 1 AND cw_holiday_entry_holiday_data.trans_status = 1';
		$holiday_info   = $this->runQuery($holiday_qry);
		$holiday_result = $this->result($holiday_info);
		if($holiday_info){
			if(count($holiday_result ?? []) > 0){
				return $this->returnResult(TRUE,'Success',array("holiday_result" => $holiday_result), []);
			}else{
				return $this->returnResult(TRUE,'No data Avaliable..',[], []);
			}
		}else{
            return $this->returnResult(FALSE,'Please Try After Some Time..',[], []);
		}
	}
	# GET FINANCIAL YEAR
	public function financialYear($json){
		$this->validate_jwt(); # JWT TOKEN
        $code             = $json->code;
		$financial_qry    = 'SELECT MIN(start_date) as start_date,MAX(end_date) as end_date FROM cw_financial_setting WHERE cw_financial_setting.trans_status = 1';
		$financial_info   = $this->runQuery($financial_qry);
		$financial_rslt   = $this->result($financial_info);		
		if($financial_info){
			if(count($financial_rslt ?? []) > 0){
				return $this->returnResult(TRUE,'Success',array("fin_result" => $financial_rslt), []);
			}else{
				return $this->returnResult(TRUE,'No data Avaliable.. Please Contact HR..',[], []);
			}
		}else{
            return $this->returnResult(FALSE,'Please Try After Some Time..',[], []);
		}
	}
	# LEVEL ONE ENCRYPTION
	function encryptAES($data, $key) {
		$iv = openssl_random_pseudo_bytes(16); // Generate a 16-byte IV
		$encrypted = openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
		return json_encode([
			'iv' => base64_encode($iv),
			'data' => base64_encode($encrypted),
		]);
	}
	
	# LEVEL TWO ENCRYPTION
	function encryptBase64WithHash($data, $secretKey) {
		$base64Data = base64_encode($data);
		$hash = base64_encode(hash_hmac('sha256', $base64Data, $secretKey, true));
		return $base64Data . '.' . $hash;
	}

								# DECRYPTION
	
	# LEVEL ONE DECRYPTION
	function decryptBase64WithHash($encryptedData, $secretKey) {
		list($base64Data, $hash) = explode('.', $encryptedData ?? "");
		$computedHash = base64_encode(hash_hmac('sha256', $base64Data, $secretKey, true));
		if ($hash !== $computedHash) {
			throw new Exception('Hash verification failed. Data may have been tampered with.');
		}
		return base64_decode($base64Data);
	}

	# LEVEL TWO DECRYPTION
	function decryptAES($encryptedData, $key) {
		$data = json_decode($encryptedData, true);
		if (!$data || !isset($data['iv'], $data['data'])) {
			throw new Exception('Invalid encrypted data format.');
		}
		$iv = base64_decode($data['iv']);
		$encrypted = base64_decode($data['data']);    
		$decrypted = openssl_decrypt($encrypted, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
		return $decrypted;
	}

	# MY PUNCHES
	public function myPunches($json){
		$validate_jwt  = $this->validate_jwt(); # JWT TOKEN
		$deviceCode    = $json->deviceCode;		
		$date          = date('Y-m-d',strtotime($json->date));
		// $code          = $validate_jwt->code;
		$emp_qry       = 'SELECT employee_code FROM cw_employees WHERE cw_employees.trans_status = 1 AND device_code = "'.$deviceCode.'"';
		$emp_info      = $this->runQuery($emp_qry);
		$emp_rslt      = $this->result($emp_info);
		$code          = $emp_rslt[0]->employee_code;
		if(!$code){
			return $this->returnResult(TRUE,'Device Code Not Found..',[], []);
			exit(0);
		}
		$shift_qry     = 'SELECT in_time,out_time,shift_status FROM cw_shift_master INNER JOIN cw_shift_import on cw_shift_import.shift_name =  cw_shift_master.prime_shift_master_id WHERE employee_code = "'.$code.'" and shift_date = "'.$date.'"';
		$shift_info    = $this->runQuery($shift_qry); 
		$shift_rslt    = $this->result($shift_info);
		if(!$shift_rslt){
			return $this->returnResult(TRUE,'Shift Not Allocated..',[], []);
			exit(0);
		}
		$shift_status  = $shift_rslt[0]->shift_status;
		$in_time       = $shift_rslt[0]->in_time;
		$out_time      = $shift_rslt[0]->out_time;
		$prev_date     = date("Y-m-d", strtotime($date . " -1 day"));
		$next_date     = date("Y-m-d", strtotime($date . " +1 day"));
		
		if((int)$shift_status === 1){
			$start  = "$date $in_time";
			$end    = "$next_date $out_time";
		}else
		if((int)$shift_status === 2){
			$start  = "$date $in_time";
			$end    = "$next_date $out_time";
		}else
		if((int)$shift_status === 3){
			$start  = "$prev_date $in_time";
			$end    = "$date $out_time";
		}

		# GET PUNCH DATA FROM TIME LOG
		$get_data_qry     = 'SELECT log_date AS log_time,IF(machine_type = 1,"In","Out") as record_type,location,cw_device.device_name,in_out_img FROM cw_time_log INNER JOIN cw_device ON cw_device.device_id = cw_time_log.device_id  WHERE user_id = "'.$deviceCode.'" AND log_date between "'.$start.'" and "'.$end.'" AND cw_time_log.trans_status = 1 order by log_date DESC';
		$get_data_info    = $this->runQuery($get_data_qry);
		$get_data_rslt    = $this->result($get_data_info);
		if(count($get_data_rslt ?? []) > 0){
			return $this->returnResult(TRUE,'Success',array("punch_result" => $get_data_rslt), []);
		}else{
			return $this->returnResult(TRUE,'No data Avaliable..',[], []);
		}
	}
	public function calInfo($json){
		$employee_code  = $json->code;
		$date           = $json->date;
        $action         = 'calInfo';
		$get_events     = $this->get_events($employee_code,$date,$date,$action);
		return $get_events;
	}

	# GET FINANCIAL SETTING INFO API
	public function finInfo($json){
		$validate_jwt  = $this->validate_jwt(); # JWT TOKEN
		$fin_info      = $this->financial_setting_info();
		return $this->returnResult(TRUE, 'Success', $fin_info[0], []);
	}
	// MYTEAMPUNCHES ON THE GET LOG DATA _ARN 07-10-2025
	public function myTeamPunches($json){
		$this->validate_jwt(); # JWT TOKEN
		$date            = date('Y-m-d', strtotime($json->date));
		$report_code     = $json->reportingCode;
		$key             = $json->key;
		$checkin_mode    = (!isset($json->checkinMode) || trim($json->checkinMode) === '') ? "1" : $json->checkinMode;

		//AND cw_employees.checkin_mode = '".$checkin_mode."'
		# Query 1: Employees who checked in
		$checkin_qry = "SELECT COUNT(*) AS log_count, cw_employees.employee_code, cw_employees.emp_name,cw_employees.device_code FROM cw_time_log JOIN cw_employees ON cw_employees.device_code = cw_time_log.user_id WHERE cw_employees.termination_status != 1 AND cw_time_log.trans_status = 1 AND (first_level_approval = '".$report_code."' OR second_level_approval = '".$report_code."')  AND DATE(cw_time_log.log_date) = '".$date."' GROUP BY cw_time_log.user_id, cw_employees.employee_code, cw_employees.emp_name";
		
		//AND e.checkin_mode = '".$checkin_mode."'
		# Query 2: Employees who did NOT check in
		//$unpunch_qry = "SELECT cw_employees.employee_code, cw_employees.emp_name,cw_employees.device_code, 0 AS log_count FROM cw_employees LEFT JOIN cw_time_log ON cw_employees.device_code = cw_time_log.user_id AND DATE(cw_time_log.log_date) = '".$date."'AND cw_time_log.trans_status = 1 AND manager_report = '".$report_code."' WHERE cw_employees.termination_status != 1 AND cw_time_log.user_id IS NULL";
		$unpunch_qry = "SELECT e.employee_code,e.emp_name,e.device_code,0 AS log_count FROM cw_employees e LEFT JOIN cw_time_log t ON e.device_code = t.user_id AND DATE(t.log_date) = '".$date."' AND t.trans_status = 1 WHERE e.termination_status != 1  AND (first_level_approval = '".$report_code."' OR second_level_approval = '".$report_code."') AND t.user_id IS NULL";
		# Run both queries
		$checkin_info = $this->runQuery($checkin_qry);
		$checkin_rslt = $this->result($checkin_info);
		$checkinCount = count($checkin_rslt ?? []);

		$unpunch_info = $this->runQuery($unpunch_qry);
		$unpunch_rslt = $this->result($unpunch_info);
		$unpunchCount = count($unpunch_rslt ?? []);

		# Choose which dataset to return based on key
		if($key === "checkin"){
			$dataList = $checkin_rslt;
		}else{
			$dataList = $unpunch_rslt;
		}

		return $this->returnResult(TRUE,($checkinCount > 0 || $unpunchCount > 0) ? 'Success' : 'No data available..',
		array("checkinCount"  => $checkinCount,"unpunchCount"  => $unpunchCount,"punch_result"  => $dataList),[]);
	}

	// MINIMUM ALLOWED DATE CHECK
	public function max_backdate_validation($user_role, $post_data){
		$company_info   = $this->company_info();
		$max_allow_date = (int)$company_info[0]->max_allow_date;
		$max_date_based = $company_info[0]->max_date_based;

		// Only if rule enabled
		if($max_allow_date <= 0){
			return true;
		}

		$max_date_based_arr = explode(',', $max_date_based);

		// Only for allowed roles
		if(!in_array($user_role, $max_date_based_arr)){
			return true;
		}

		$min_allowed_date = date('Y-m-d', strtotime("-".$max_allow_date." days"));

		// Detect correct date field
		if(isset($post_data['from_date'])){
			$from_date = date('Y-m-d', strtotime($post_data['from_date']));
		}else
		if(isset($post_data['shift_date'])){
			$from_date = date('Y-m-d', strtotime($post_data['shift_date']));
		}else
		if(isset($post_data['in_date'])){
			$from_date = date('Y-m-d', strtotime($post_data['in_date']));

		}else if(isset($post_data['permission_date'])){
			$from_date = date('Y-m-d', strtotime($post_data['permission_date']));
		}else{
			return true;
		}

		if($from_date < $min_allowed_date){
			$display_date = date('d-m-Y', strtotime($min_allowed_date));
			echo $this->returnResult(FALSE,"You can apply only from ".$display_date,[],[]);
			exit(0);
		}

		return true;
	}
}
?>