<?php
//akmal 2021:leave version 2. revamp leave module 
if (!defined('BASEPATH')) exit('No direct script access allowed');

/** @author akmal,farid,arep,fakhru */
class Leave_v2 extends MY_Controller{
	
	function __construct()	{
		parent::__construct();

		if($this->logged_user = $this->session->userdata('user'))		{
			$this->login->checkModuleAccess(4); //modules/hr/admin/controller/login, 4=leave module

			$this->logged_module = $_SESSION['module_data'];

			$this->load->model('admin/model_user');	
			$this->load->model('admin/model_company');	
			$this->load->model('hr/model_leave_v2','model_leave');
			$this->load->model('hr/model_exam');
			$this->load->model('admin/model_general'); 
		}
		else 		{
			redirect(base_url());
		}
	}

	function index() {
		$today = date('Y-m-d');
		$a_week_from_today = date('Y-m-d', strtotime("+7 day", strtotime('now')));

		$user_info = NULL; 
		$department_staffs = $this->model_leave->getLeaveStatusByDepartment($this->logged_user['department_id'], NULL, $today, NULL); //check who are onleave today

		// GENERAL
		$data = array(
			'page_setup'   => $this->template->pageSetup('HR', '', 'Leave Dashboard'),
			'types' 	   => $this->model_leave->getLeaveType(),
			'periods' 	   => $this->model_leave->getRefPeriod(),
			'departments'  => $this->model_company->getDepartments(),
			'staffs' 	   => $this->model_general->fetchAll('user', array('id, staff_id, name'), array('is_delete' => 0), array(), array('name'=>'asc'), array()), 
			'applications' => $this->model_leave->getApplication2(array('a.status IN (1,2)')),
			'department'   => array(
				'staffs' 	   => $department_staffs,
				'applications' => $this->model_leave->getLeaveBetweenDateWithFilters($today, $a_week_from_today, array('a.status in (1,2)', 'a.department_id' => $this->logged_user['department_id']))
			),
			'logged_user'  => array(
				'user'		   => $this->model_user->getUsers($this->logged_user['id']),
				'leave_info'   => $this->model_leave->getLeaveInfo(array('user_id = ' => $this->logged_user['id'], 'year(date_from) = ' => date('Y'))),
				'allocations'  => $this->model_leave->getAllocation_currentYear(array('a.user_id' => $this->logged_user['id'] ), false), // show users leave allocation
				'applications' => $this->model_leave->getApplication(array('a.user_id' => $this->logged_user['id']), 5), 		  // show users leave history
				'prorate' 	   => $this->getProRate_old($this->logged_user['id'])
			)
		);

		//die(debug($data['logged_user']['applications']));

		//ADMIN
		if (strtolower($this->logged_module['role']) == 'admin') {
			$data['managers'] = $this->model_user->getUsersByFilter(array('e.parent_id <' => 3));
			// $data['statistics'] = $this->model_leave->getStatistics();
		}

		/**
		 * TODO: Leave Statistics
		 * Show frequency of leave
		 * Leave applications percentage of applied by type, month
		 * Show leave trends
		 */

		$this->template->view('hr/leave_v2/leave_home', $data);
	}

	function getPendingTotalDays($user_id, $leave_type = null, $year = null) {
		$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

		$types		  = $this->model_leave->getLeaveType();
		$allocations  = $this->model_leave->getAllocation(array('a.user_id' => $user_id, 'a.year' => date('Y')));

		// $applications = $this->model_leave->getApplication(array('a.user_id' => $user_id, 'a.status' => 1, 'year(a.date_to)' => date('Y')));

		if ($allocations) {
			$total_pending_by_type = array();

			foreach ($types as $type) {
				$total_pending_by_type[$type['code']] = 0;
				$applications = $this->model_leave->getApplication(array('a.user_id' => $user_id, 'a.type_id' => $type['id'], 'a.status' => 1, 'year(a.date_to)' => date('Y')));
				if (!is_null($applications)) foreach ($applications as $application) $total_pending_by_type[$type['code']] += floatval($application['days_applied']);
			}

			debug($total_pending_by_type);
			die();
		}
	}

	function history($year=null, $user_id=null) {
		$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

		$data = array(
			'page_setup' => $this->template->pageSetup('HR', '', 'Leave Dashboard'),
		);

		$this->template->view('hr/leave/history', $data);
	}

	function myAllocation(){ 
		var_dump($this->logged_user);
		$data = $this->input->post();		
		$data['year'] = (empty($data['year']))?date("Y"):$data['year']; 
		$data['user_id'] = $this->logged_user['id'];
		
		$data['user']  		 = $this->model_user->getUsers($data['user_id']);
		$data['allocations'] = $this->model_leave->getAllocation2(array('a.user_id' => $data['user_id'], 'a.year' => $data['year']),false);
					
		$data['page_setup'] = $this->template->pageSetup('HR', '',$data['user']['name'].'\'s Leave Balance for the year '.$data['year']);
		
		$this->template->view('hr/leave_v2/usersAllocationList', $data);
	}
	function allocation($year=null, $dept_id=null, $user_id=null) {
		$data['types'] 		 = $this->model_leave->getLeaveType();
		$data['categories']  = $this->model_general->fetchAll('company__position', array(), array('parent_id' => 0));
		$data['departments'] = $this->model_company->getDepartments();
		$data['leave_types'] = $this->model_leave->getLeaveType(); 

		if($this->validateDate($year, 'Y')) {
			$data['year'] = $year;

			if($dept_id) {
				$data['department'] = $this->model_company->getDepartments(null, $dept_id);

				if ($user_id) {
					$data['user']  		 = $this->model_user->getUsers($user_id);
					$data['allocations'] = $this->model_leave->getAllocation2(array('a.user_id' => $user_id, 'a.year' => $year),false);
					
					// $data['unallocated_types'] = $this->model_leave->getUnallocatedLeaveTypes(array('year' => $year, 'user_id' => $user_id));
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['user']['name'].'\'s Leave Balance for the year '.$year);
					$this->template->view('hr/leave/usersAllocationList', $data);

				} else {
					// $data['users'] = $this->model_user->getUsersByFilter(array('d.department_id' => $dept_id));
					$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'], 'd.department_id' => $dept_id,'j.year'=>$year));
					
					// show department allocation detail
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['department']['name'].'\'s Allocation List for the year '.$year);

					$this->template->view('hr/leave/departmentsAllocationList', $data);
				}

			} else {
				// $users = $this->model_user->getUsersByFilter(array('d.company_id' => $this->logged_user['company_id']));
				// akmal 20181207 to include type_id in a single select statement 
				$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'],'j.year'=>$year));

				for ($i=0; $i < count($data['users']); $i++) { 
					$allocation_ids = explode(',', $data['users'][$i]['allocation_id']);
					$type_ids 		= explode(',', $data['users'][$i]['type_id']);

					$allocations = array();

					for ($j=0; $j < count($type_ids); $j++) $allocations[$type_ids[$j]] = $allocation_ids[$j];

					$data['users'][$i]['allocations'] = $allocations;
				} 

				$data['page_setup'] = $this->template->pageSetup('HR', '', $year.' Allocation List');
				$this->template->view('hr/leave_v2/allocationUsersList', $data);
			}

		} else {
			$this->allocation_year();
//or //			redirect(base_url().'hr/leave_v2/allocation_year';
		}
	}
	function allocation_year(){ 
		$data['rsYears'] = $this->model_leave->getAllocationYears();
		$data['rsUnAllocatedUserByYear'] = $this->model_leave->getUnallocatedUserByYear();
 
		// show list of years and overall status
		$data['page_setup'] = $this->template->pageSetup('HR', '','Leave Allocation Year List');
		$this->template->view('hr/leave_v2/allocationList', $data);
	}
	function allocation_print($year=null, $dept_id=null, $user_id=null) {
		$data['types'] 		 = $this->model_leave->getLeaveType();
		$data['categories']  = $this->model_general->fetchAll('company__position', array(), array('parent_id' => 0));
		$data['departments'] = $this->model_company->getDepartments();
		$data['leave_types'] = $this->model_leave->getLeaveType();

		if($this->validateDate($year, 'Y')) {
			$data['year'] = $year;

			if($dept_id) {
				$data['department'] = $this->model_company->getDepartments(null, $dept_id);

				if ($user_id) {
					$data['user']  = $this->model_user->getUsers($user_id);
					$data['allocations'] = $this->model_leave->getAllocation2(array('a.user_id' => $user_id, 'a.year' => $year));

					// $data['unallocated_types'] = $this->model_leave->getUnallocatedLeaveTypes(array('year' => $year, 'user_id' => $user_id));
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['user']['name'].'\'s Leave Balance for the year '.$year);
					$this->template->view('hr/leave/usersAllocationList_print', $data);

				} else {
					// $data['users'] = $this->model_user->getUsersByFilter(array('d.department_id' => $dept_id));
					$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'], 'd.department_id' => $dept_id,'j.year'=>$year));


					// show department allocation detail
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['department']['name'].'\'s Allocation List for the year '.$year);

					$this->template->view('hr/leave/departmentsAllocationList_print', $data);
				}

			} else {
				// $users = $this->model_user->getUsersByFilter(array('d.company_id' => $this->logged_user['company_id']));
				// akmal 20181207 to include type_id in a single select statement 
				$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'],'j.year'=>$year)); 

				$data['page_setup'] = $this->template->pageSetup('HR', '', $year.' Allocation List');
				$this->template->view('hr/leave/allocationUsersList_print', $data);
			}

		}else $this->allocation();	
	}

	function newAllocation($year=null) {
		$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

/*		// akmal 20191128 there was no checking of enttilement. running allocation with no entitlement cause system hung. check for entitlement before run allocation 
		// die(debug(count($users)));
		 insert into hr__leave_allocation (user_id,  entitlement_id, year, date_from, date_to, type_id, leave_balance, leave_entitled)
		select a.user_id,  c.id as entitlement_id, 2020 as year, '2020-01-01', '2020-12-31', 1 as type_id,  
		if(a.leave_entitled < b.entitled_leave,b.entitled_leave,if(a.leave_entitled + 1 < c.max_entitlement,a.leave_entitled + 1,c.max_entitlement)) as leave_balance,
		if(a.leave_entitled < b.entitled_leave,b.entitled_leave,if(a.leave_entitled + 1 < c.max_entitlement,a.leave_entitled + 1,c.max_entitlement)) as new_entitlement 
		from hr__leave_allocation a , hr__leave_entitlement b, hr__leave_entitlement c 
		where a.entitlement_id = b.id and a.year = b.year
		and c.year = 2020  and c.category_id = b.category_id
		and c.type_id = 1
		and a.year = 2018 and a.type_id = 1 
		and a.leave_entitled > 0
		order by a.user_id
		and a.year = 2018 and a.type_id = 1 
		and a.leave_entitled > 0
		order by a.user_id 		*/
		if(!$this->checkEntitlement($year,1) || !$this->checkEntitlement($year,3)) 
		{
			echo 'false'; 
			$this->session->set_flashdata('error','You need to set leave entitlement before run leave allocation.');
			redirect(base_url('hr/leave/entitlement/'));
		} 

		$data = array(
			'year' 				 => $year,
			'allocated_staffs'   => $this->model_leave->getAllocatedUser(array('year' => $year)),
			'unallocated_staffs' => $this->model_leave->getUnallocatedUser2(array('year' => $year)),
			'unable_staffs'  	 => $this->model_leave->getUnableToAllocateUser()
		);

		if (!empty($data['unallocated_staffs'])) {
			for ($i=0;  $i< count($data['unallocated_staffs']) ; $i++) { 
				$user = array('date_joined' => $data['unallocated_staffs'][$i]['date_joined']);

				$entitlement = array(
					'max_entitlement' 			 => $data['unallocated_staffs'][$i]['al_max_entitlement'],
					'entitled_leave' 			 => $data['unallocated_staffs'][$i]['al_entitled_leave'],
					'month_of_service_add_leave' => $data['unallocated_staffs'][$i]['al_month_cycle'],
					'additional_leave' 			 => $data['unallocated_staffs'][$i]['al_additional_leave_per_cycle']
				);

				//$data['unallocated_staffs'][$i]['additional_leave'] = $this->countAdditionalLeave3($year, $user, $entitlement);
				//$data['unallocated_staffs'][$i]['additional_leave'] = $this->countAdditionalLeave4($year, $user, $entitlement);

				$allowed_bring_forward = floatval($data['unallocated_staffs'][$i]['al_entitled_leave']) * (floatval($data['unallocated_staffs'][$i]['al_bring_forward_percentage']) / 100);
				$total_al_balance 	   = floatval($data['unallocated_staffs'][$i]['prev_al_balance']) + floatval($data['unallocated_staffs'][$i]['prev_co_balance']);
				$bring_forward 		   = (floatval($total_al_balance) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($total_al_balance);
				
				$duration = $this->getDuration($data['unallocated_staffs'][$i]['date_joined'], $year.'-01-01');

				if (($duration / 12) < 2) {
					$data['unallocated_staffs'][$i]['mc_allocation'] = number_format(14.0, 1);
				} else if (($duration / 12) >= 2 && ($duration / 12) < 5) {
					$data['unallocated_staffs'][$i]['mc_allocation'] = number_format(18.0, 1);
				} else {
					$data['unallocated_staffs'][$i]['mc_allocation'] = number_format(22.0, 1);
				}

				$data['unallocated_staffs'][$i]['bring_forward'] = $bring_forward;
				
				$data['unallocated_staffs'][$i]['al_allocation'] = $data['unallocated_staffs'][$i]['al_entitled_leave'];
				$data['unallocated_staffs'][$i]['additional_leave'] = 0;
				//var_dump($data['unallocated_staffs'][$i]); die(); 

				//var_dump(date_create($data['unallocated_staffs'][$i]['date_joined'])); 
				//var_dump(date_create($year.'-01-01')); 				
				$interval = date_diff(date_create($data['unallocated_staffs'][$i]['date_joined']), date_create($year.'-01-01'));
				//var_dump($interval); 
				$data['unallocated_staffs'][$i]['monthDiff'] = ($interval->y * 12) + $interval->m;
				if($data['unallocated_staffs'][$i]['al_month_cycle'] == NULL) 
					$data['unallocated_staffs'][$i]['al_month_cycle'] = 24; 
				
				if (date("Y",strtotime($data['unallocated_staffs'][$i]['date_joined'])) < ($year - 2)) {
					if($data['unallocated_staffs'][$i]['prev_al_last2year'] == NULL) {
				//additional leave = additional leave per cycle X total month of service / leave cycle
				//var_dump($data['unallocated_staffs'][$i]['al_additional_leave_per_cycle']);
				//var_dump($data['unallocated_staffs'][$i]['monthDiff']);
				//var_dump($data['unallocated_staffs'][$i]['al_month_cycle']);
				//echo (int)(	$data['unallocated_staffs'][$i]['monthDiff']/$data['unallocated_staffs'][$i]['al_month_cycle']); 
 				
						$data['unallocated_staffs'][$i]['additional_leave'] = $data['unallocated_staffs'][$i]['al_additional_leave_per_cycle'] * (int)(	$data['unallocated_staffs'][$i]['monthDiff'] / $data['unallocated_staffs'][$i]['al_month_cycle']);
						
						$data['unallocated_staffs'][$i]['al_allocation'] = $data['unallocated_staffs'][$i]['al_entitled_leave'] + $data['unallocated_staffs'][$i]['additional_leave'];
					} else {
						$data['unallocated_staffs'][$i]['additional_leave'] = $data['unallocated_staffs'][$i]['al_additional_leave_per_cycle'] * (int)($data['unallocated_staffs'][$i]['monthDiff'] / $data['unallocated_staffs'][$i]['al_month_cycle']);
						
						$data['unallocated_staffs'][$i]['al_allocation'] = $data['unallocated_staffs'][$i]['al_entitled_leave'] + $data['unallocated_staffs'][$i]['additional_leave'];
					}
					
				} else {
					$data['unallocated_staffs'][$i]['al_allocation'] = $data['unallocated_staffs'][$i]['al_entitled_leave'];
				}
				
				//check if allocation > max entitlement 				
				$data['unallocated_staffs'][$i]['al_allocation'] = ($data['unallocated_staffs'][$i]['al_allocation'] > $data['unallocated_staffs'][$i]['al_max_entitlement'])?$data['unallocated_staffs'][$i]['al_max_entitlement']:$data['unallocated_staffs'][$i]['al_allocation'] ;				

				//check if allocation < last year allocation 				
				$data['unallocated_staffs'][$i]['al_allocation'] = ($data['unallocated_staffs'][$i]['al_allocation'] < $data['unallocated_staffs'][$i]['prev_al'])?$data['unallocated_staffs'][$i]['prev_al']:$data['unallocated_staffs'][$i]['al_allocation'] ;				
				//if ($data['unallocated_staffs'][$i]['al_month_cycle']==0) {
				//var_dump($data['unallocated_staffs'][$i]); //die(); }

				//				$data['unallocated_staffs'][$i]['al_allocation'] = floatval($data['unallocated_staffs'][$i]['al_entitled_leave']) + floatval($data['unallocated_staffs'][$i]['additional_leave']['total_additional_leave']);
			}
		}

		$data['page_setup'] = $this->template->pageSetup('HR', '','New Leave Allocation');
		$this->template->view('hr/leave/newAllocation', $data);
	}

	function getNewAllocation() {
		$data = $this->input->get();

		if ($data['id'] && $data['year'] && $data['category_id']) {
			$staff = $this->model_user->getUsers($data['id']);
			$prev_al_allocation = $this->model_leave->getAllocation(array('a.user_id' => $data['id'], 'a.type_id' => 1, 'a.year' => $data['year'] - 1));
			$prev_co_allocation = $this->model_leave->getAllocation(array('a.user_id' => $data['id'], 'a.type_id' => 8, 'a.year' => $data['year'] - 1));
			$al_entitlement  	= $this->model_leave->getEntitlement(array('a.category_id' => $data['category_id'], 'a.type_id' => 1, 'a.year' => $data['year']));
			$mc_entitlement  	= $this->model_leave->getEntitlement(array('a.category_id' => $data['category_id'], 'a.type_id' => 3, 'a.year' => $data['year']));

			$duration = $this->getDuration($staff['date_joined'], $data['year'].'-01-01');

			if (($duration / 12) < 2) {
				$mc_entitled_curr = number_format(14.0, 1);
			} else if (($duration / 12) >= 2 && ($duration / 12) < 5) {
				$mc_entitled_curr = number_format(18.0, 1);
			} else {
				$mc_entitled_curr = number_format(22.0, 1);
			}

			$allowed_bring_forward = floatval($prev_al_allocation['leave_entitled']) * (floatval($al_entitlement['bring_forward_percentage']) / 100);
			$total_al_balance 	   = floatval($prev_al_allocation['leave_balance']) + floatval($prev_co_allocation['leave_balance']);
			$bring_forward 		   = (floatval($total_al_balance) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($total_al_balance);
			// $additional_leave	   = $this->countAdditionalLeave($data['id'], $data['year']);
			$additional_leave	   = $this->countAdditionalLeave2($data['id'], $data['year']);
			$al_allocation 		   = floatval($al_entitlement['entitled_leave']) + floatval($additional_leave['total_additional_leave']);
			// $al_allocation 		   = $prev_al_allocation['leave_entitled'] + $additional_leave['additional_leave'];

			$res = array(
				'status' => 'Success',
				'new_allocation' => array(
					'al_entitlement_id' => $al_entitlement['id'],
					'entitled_leave' 	=> $al_entitlement['entitled_leave'],
					'bring_forward' 	=> $bring_forward,
					'al_allocation' 	=> $al_allocation,
					'mc_entitlement_id' => $mc_entitlement['id'],
					'mc_allocation' 	=> $mc_entitled_curr,
					'additional_leave'  => $additional_leave
				)
			);
			
			print json_encode($res);
		} else {
			$error = array();

			if (!$data['id']) 		   $error[] = 'No User Submitted.';
			if (!$data['year']) 	   $error[] = 'No Year Submitted.';
			if (!$data['category_id']) $error[] = 'Staff Position is not yet setup.';

			print json_encode(array(
				'status' => 'Failed',
				'message' => $error
			));
		}
	}

	function getDuration($date_from, $date_to) {
		$date_from = DateTime::createFromFormat('Y-m-d', $date_from);
		$date_to   = DateTime::createFromFormat('Y-m-d', $date_to);

		return $duration = ($date_from && $date_to) ? $date_from->diff($date_to)->m + ($date_from->diff($date_to)->y*12) : 0;
	}

	function reports_entitlement($year = null) {
		$year  = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		// $users = $this->model_user->getUsers();
		$users = $this->model_leave->getUserReview(array('year' => $year));

		$staffs_allocation = array();

		foreach($users as $staff) {
			$mc_entitled_curr = number_format(0.0, 1);

			if ($staff['date_joined']) {
				$duration = $this->getDuration($staff['date_joined'], $year.'-01-01');

				if (($duration / 12) < 2) {
					$mc_entitled_curr = number_format(14.0, 1);
				} else if (($duration / 12) >= 2 && ($duration / 12) < 5) {
					$mc_entitled_curr = number_format(18.0, 1);
				} else {
					$mc_entitled_curr = number_format(22.0, 1);
				}
			}

			$user = array('date_joined' => $staff['date_joined']);

			$entitlement = array(
				'max_entitlement' 			 => $staff['al_max_entitlement'],
				'entitled_leave' 			 => $staff['al_entitled_leave'],
				'month_of_service_add_leave' => $staff['al_month_cycle'],
				'additional_leave' 			 => $staff['al_additional_leave_per_cycle']
			);

			$staff['additional_leave'] = $this->countAdditionalLeave3($year, $user, $entitlement);

			$allowed_bring_forward = floatval($staff['prev_al_entitled']) * (floatval($staff['al_bring_forward_percentage']) / 100);
			$total_al_balance 	   = floatval($staff['prev_al_balance']) + floatval($staff['prev_co_balance']);
			$bring_forward 		   = (floatval($total_al_balance) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($total_al_balance);
			$encashment			   = (($total_al_balance - $bring_forward) > 0) ? ($total_al_balance - $bring_forward) / 2 : 0;
			
			$duration = $this->getDuration($staff['date_joined'], $year.'-01-01');

			$years = floor($duration / 12);
			$months = $duration % 12;

			$staff['years_of_service'] = $years. ' y '.$months.' m';

			if (($duration / 12) < 2) {
				$staff['mc_allocation'] = number_format(14.0, 1);
			} else if (($duration / 12) >= 2 && ($duration / 12) < 5) {
				$staff['mc_allocation'] = number_format(18.0, 1);
			} else {
				$staff['mc_allocation'] = number_format(22.0, 1);
			}

			$staff['bring_forward'] = $bring_forward;
			$staff['al_allocation'] = floatval($staff['al_entitled_leave']) + floatval($staff['additional_leave']['total_additional_leave']);

			$staffs_allocation[] = array(
				'name' 			   => $staff['name'],
				'position' 		   => $staff['position_name'].' ('.$staff['position_category'].')',
				'department' 	   => $staff['department_name'].' ('.$staff['branch_name'].')',
				'date_joined' 	   => $staff['date_joined'],
				'years_of_service' => $staff['years_of_service'],
				'al_entitled_prev' => (string) number_format(($staff['prev_al_entitled'] + $staff['prev_co_entitled']), 1),
				'al_balance_prev'  => (string) number_format($total_al_balance, 1),	
				'bring_forward'    => (string) number_format($staff['bring_forward'], 1),	
				'encashment'	   => (string) number_format($encashment, 2),
				'un_taken_prev'	   => (string) number_format($staff['prev_un_taken'], 1),
				// 'encashment'  	   => number_format((floatval($staff['prev_al_balance']) - floatval($staff['bring_forward'])) / 2, 1),	
				// 'mc_entitled_prev' => $staff['mc_previous_year_entt'],
				// 'al_entitled_curr' => ($staff['prev_al_entitled'] > $staff['al_allocation']) ? $staff['prev_al_entitled'] : (string) number_format($staff['al_allocation'], 1),
				// 'mc_entitled_curr' => $mc_entitled_curr,
				// 'additional_leave' => (string) $staff['additional_leave']['total_additional_leave'],
			);
		}

		$print_data = array(
			'title'   => 'Leave Allocation Review For The Year '.($year - 1),
			// 'headers' => array('Name', 'Position', 'Department', 'Date Joined', 'Years of Service', ($year - 1).' Allocation', ($year - 1).' Balance', ($year - 1).' Bring Forward', ($year - 1).' Encashment',  $year.' Allocation',  $year.' Medical Allocation'),
			'headers' => array('Name', 'Position', 'Department', 'Date Joined', 'Years of Service', ($year - 1).' Allocation', ($year - 1).' Balance', ($year - 1).' Bring Forward', ($year - 1).' Encashment', ($year - 1).' Unpaid Taken'),
			'body' 	  => $staffs_allocation,
		);

		$this->report_template($print_data);
	}

	function getNewAllocationBulk() {
		$data = $this->input->get();

		if($data['year'] && count($data['users']) > 0) {
			$users_allocation = array();
			
			foreach ($data['users'] as $user) {
				$staff = $this->model_user->getUsers($user['id']);
				$duration = $this->getDuration($staff['date_joined'], $data['year'].'-01-01');

				if (($duration / 12) < 2) {
					$mc_entitled_curr = number_format(14.0, 1);
				} else if (($duration / 12) >= 2 && ($duration / 12) < 5) {
					$mc_entitled_curr = number_format(18.0, 1);
				} else {
					$mc_entitled_curr = number_format(22.0, 1);
				}

				$prev_al_allocation = $this->model_leave->getAllocation(array('a.user_id' => $user['id'], 'a.type_id' => 1, 'a.year' => $data['year'] - 1));
				$prev_co_allocation = $this->model_leave->getAllocation(array('a.user_id' => $user['id'], 'a.type_id' => 8, 'a.year' => $data['year'] - 1));
				$al_entitlement  	= $this->model_leave->getEntitlement(array('a.category_id' => $user['category_id'], 'a.type_id' => 1, 'a.year' => $data['year']));
				$mc_entitlement  	= $this->model_leave->getEntitlement(array('a.category_id' => $user['category_id'], 'a.type_id' => 3, 'a.year' => $data['year']));

				$allowed_bring_forward = floatval($prev_al_allocation['leave_entitled']) * (floatval($al_entitlement['bring_forward_percentage']) / 100);
				$total_al_balance 	   = floatval($prev_al_allocation['leave_balance']) + floatval($prev_co_allocation['leave_balance']);
				$bring_forward 		   = (floatval($total_al_balance) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($total_al_balance);
				// $additional_leave	   = $this->countAdditionalLeave($user['id'], $data['year']);
				$additional_leave	   = $this->countAdditionalLeave2($user['id'], $data['year']);
				$al_allocation 		   = floatval($al_entitlement['entitled_leave']) + floatval($additional_leave['total_additional_leave']);
				// $al_allocation 		   = $prev_al_allocation['leave_entitled'] + $additional_leave['additional_leave'];

				$allocation_data = array(
					'user_id' => $user['id'],
					'new_allocation' => array(
						'al_entitlement_id' => $al_entitlement['id'],
						'entitled_leave' 	=> $al_entitlement['entitled_leave'],
						'bring_forward' 	=> $bring_forward,
						'al_allocation' 	=> $al_allocation,
						'mc_entitlement_id' => $mc_entitlement['id'],
						'mc_allocation' 	=> $mc_entitled_curr,
						'additional_leave'	=> $additional_leave
					),
				);
				
				array_push($users_allocation, $allocation_data);
			}

			print json_encode(array(
				'status' => 'Success',
				'users' => $users_allocation
			));
		} else {
			print json_encode(array(
				'status' => 'Failed'
			));
		}
	}

	function application($user_id=null, $year=null, $mode='default') {
		$user_id 	  	   = ($user_id && strtolower($this->logged_module['role']) != 'user') ? $user_id : $this->logged_user['id'];
		$year 	 	  	   = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		$data['years'] 	   = $this->model_leave->getEntitlementYears();
		$data['curr_year'] = $year;
		$data['user'] 	   = $this->model_user->getUsers($user_id);
		$data['user_id'] 	   = $user_id; 
		$data['mode'] = $mode; 

		if($mode == 'print') {
			$print_data = array(
				'title'   => strtoupper($data['user']['name']).'\'S LEAVE APPLICATION LIST REPORT FOR THE YEAR '.$year,
				'headers' => array('Applicant', 'Date From', 'Date To', 'Days', 'Leave Type', 'Status', 'Relief Person'),
				'body' 	  => $this->model_leave->getApplication(array('a.user_id' => $data['user']['id'], 'year(a.date_from) >=' => $year), null, 'print'),
			);

			$this->report_template($print_data);
		} else {
			$data['today']			= new DateTime(date('Y-m-d'));
			$data['year']			= $year;

			$data['relief_persons'] = $this->model_user->getUsersByFilter(null);

			$data['allocations']  	= $this->model_leave->getAllocation_currentYear(array('a.user_id' => $data['user_id']));
			$data['requests']  		= $this->model_leave->getRequest(array('user_id' => $data['user']['id'], 'year' => $year)); 
			$data['applications'] 	= $this->model_leave->getApplication(array('a.user_id' => $data['user_id'], 'year(a.date_from) >=' => $year));
if ($mode=='debug') { echo '<br>2. before leave info (query ni slow)<br>'.$this->db->last_query(); var_dump($data['user_id']); var_dump($year); }
			$data['leave_info'] 	= $this->model_leave->getLeaveInfo(array('user_id = ' => $data['user_id'], 'year(date_from) = ' => $year));
			
if ($mode=='debug') {  echo '<br>3. leave info<br>'.$this->db->last_query(); var_dump($data['leave_info']); } 
			$data['leave_types'] 	= $this->model_leave->getLeaveType();
			$data['leave_periods'] 	= $this->model_leave->getRefPeriod();
			
			
			$data['prorate']		= 0; 
			
//$this->getProRate($user_id,NULL,$mode); 
if ($mode=='debug') {  echo '<br>4. Prorate<br>'.$this->db->last_query(); var_dump($data['prorate']);} 
			$data['exam_list']		= $this->model_exam->get_valid_exam_list_by_user($user_id);
			$data['page_setup'] 	= $this->template->pageSetup('HR', '', 'Leave Application '.$year);
			
			$this->template->view('hr/leave_v2/application', $data);
		}
	}

	function admin_applications($year = null, $mode='default') {
		if (strtolower($this->logged_module['role']) != 'admin') redirect(base_url('hr/leave/application'));

		$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

		$data = array(
			'staffs'		=> $this->model_user->getUsersByFilter(),
			'curr_year' 	=> $year,
			'years' 		=> $this->model_leave->getEntitlementYears(),
			'departments'	=> $this->model_company->getDepartments2(),
			'leave_types' 	=> $this->model_leave->getLeaveType(),
			'leave_periods' => $this->model_leave->getRefPeriod(),
			'applications'	=> $this->model_leave->getApplication(array('year(a.date_from) = ' => $year)),
			'leave_info' 	=> $this->model_leave->getLeaveInfo(array('year(date_from) = ' => $year)),
			'relief_persons'    => $this->model_user->getUsersByFilter(),
			'exam_list_all' => $this->model_exam->get_exam_list(),
			'page_setup' 	=> $this->template->pageSetup('HR', '', 'Leave Application '.$year)
		);
		
		$this->template->view('hr/leave/applicationsList', $data);
	}
	function admin_leave_type_setup() {
		$data['leave_types']  = $this->model_general->fetchAll("hr__leave_type", array(), array("is_delete" => 0));
		$data['positions']    = $this->model_general->fetchAll("company__position", array(), array("is_delete" => 0, "parent_id" => 0));
		
		foreach($data['positions'] as $position){
			$data['entitlements'][$position['id']] = $this->model_general->fetchSingle("hr__leave_entitlement", array(), array("type_id"=> 1, "category_id"=> $position['id'], "is_delete" => 0));
		}

		$data['page_setup'] = $this->template->pageSetup('HR', '', 'Leave Setting');
		$this->template->view('hr/leave_v2/leave_type_setup', $data);
	}

	function admin_entitlement($year=null, $leave_type_id=null) {
		if(strtolower($this->logged_module['role']) != 'admin') redirect(base_url('hr/leave'));

		$leave_types   = $this->model_leave->getTypes();
		$data['types'] 		= $leave_types; 
		$data['years'] 		= $this->model_leave->getEntitlementYears();
		$data['categories'] = $this->model_general->fetchAll("company__position", array(), array("is_delete" => 0, "parent_id" => 0));
		$data['curr_year']  = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

		if($this->validateDate($year, 'Y')) {
			if($leave_type_id) {
				$data['leave_type'] = $this->model_leave->getLeaveType($leave_type_id);
				$data['entitlements'] = $this->model_leave->getEntitlement(array('a.year' => $year, 'a.type_id' => $leave_type_id));

				$data['page_setup'] = $this->template->pageSetup('HR', '', $data['leave_type']['name'].'\'s Entitlement '.$year);
				$this->template->view('hr/leave/entitlement', $data);

			} else {
				// all types by year
			}
			
		} else {
			foreach($leave_types as $type) {
				$data['leave_types'][$type['id']] = $type;

				foreach($data['years'] as $year) {
					$data['leave_types'][$type['id']]['entitlement'][$year['year']] = $this->model_leave->getEntitlement(array('year' => $year['year'], 'type_id' => $type['id']));
				}
			}

			$data['page_setup'] = $this->template->pageSetup('HR', '','Leave Entitlement\'s List');
			$this->template->view('hr/leave/entitlementsList', $data);
		}
	}

	function admin_allocation($year=null, $dept_id=null, $user_id=null) {
		$data['types'] 		 = $this->model_leave->getLeaveType();
		$data['categories']  = $this->model_general->fetchAll('company__position', array(), array('parent_id' => 0));
		$data['departments'] = $this->model_company->getDepartments();
		$data['leave_types'] = $this->model_leave->getLeaveType();

		if($this->validateDate($year, 'Y')) {
			$data['year'] = $year;

			if($dept_id) {
				$data['department'] = $this->model_company->getDepartments(null, $dept_id);

				if ($user_id) {
					$data['user']  		 = $this->model_user->getUsers($user_id);
					$data['allocations'] = $this->model_leave->getAllocation2(array('a.user_id' => $user_id, 'a.year' => $year),false);
					
					// $data['unallocated_types'] = $this->model_leave->getUnallocatedLeaveTypes(array('year' => $year, 'user_id' => $user_id));
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['user']['name'].'\'s Leave Balance for the year '.$year);
					$this->template->view('hr/leave/usersAllocationList', $data);

				} else {
					// $data['users'] = $this->model_user->getUsersByFilter(array('d.department_id' => $dept_id));
					$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'], 'd.department_id' => $dept_id,'j.year'=>$year));
					
					// show department allocation detail
					$data['page_setup'] = $this->template->pageSetup('HR', '',$data['department']['name'].'\'s Allocation List for the year '.$year);

					$this->template->view('hr/leave/departmentsAllocationList', $data);
				}

			} else {
				$data['users'] = $this->model_leave->getUsersLeaveAllocation(array('d.company_id' => $this->logged_user['company_id'],'j.year'=>$year));

				for ($i=0; $i < count($data['users']); $i++) { 
					$allocation_ids = explode(',', $data['users'][$i]['allocation_id']);
					$type_ids 		= explode(',', $data['users'][$i]['type_id']);

					$allocations = array();

					for ($j=0; $j < count($type_ids); $j++) $allocations[$type_ids[$j]] = $allocation_ids[$j];

					$data['users'][$i]['allocations'] = $allocations;
				}
				// echo $this->db->last_query(); var_dump($users); exit();

				$data['page_setup'] = $this->template->pageSetup('HR', '', $year.' Allocation List');
				$this->template->view('hr/leave/allocationUsersList', $data);
			}

		} else {
			$years = $this->model_leave->getAllocationYears();

			if ($years) {
				foreach ($years as $y) {
					$data['years'][$y['year']] = $y;
					$data['years'][$y['year']]['unallocated_users'] = $this->model_leave->getUnallocatedUser(array('year' => $y['year']));
				}
			}

			// show list of years and overall status
			$data['page_setup'] = $this->template->pageSetup('HR', '','Leave Allocation Year List');
			$this->template->view('hr/leave/allocationList', $data);
		}
	}

	function admin_department($dept_id=null, $year=null, $mode='default') {
		if(strtolower($this->logged_module['role']) == 'user') redirect(base_url('hr/leave'));

		$data['leave_types']   = $this->model_leave->getLeaveType();
		$data['leave_periods'] = $this->model_leave->getRefPeriod();

		$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

		$data['year'] 	   = $year;
		$data['years'] 	   = $this->model_leave->getEntitlementYears();
		$data['curr_year'] = $year;

		if($dept_id) {
			$dept_id = (strtolower($this->logged_module['role']) == 'admin') ? $dept_id : $this->logged_user['department_id'];
			$data['department'] = $this->model_company->getDepartments(null, $dept_id);

			if ($mode == 'print') {
				$print_data = array(
					'title'   => strtoupper($data['department']['name']).'\'S DEPARTMENT ('.strtoupper($data['department']['branch_name']).') LEAVE APPLICATION LIST REPORT FOR THE YEAR '.$year,
					'headers' => array('Applicant', 'Date From', 'Date To', 'Days', 'Leave Type', 'Status', 'Relief Person'),
					'body' 	  => $this->model_leave->getApplication(array('i.department_id' => $dept_id, 'j.parent_id >' => 2, 'year(a.date_from)' => $year), null, 'print')
				);

				$this->report_template($print_data);

			} else {
				$data['staffs']			   = $this->model_user->getUsersByFilter(array('d.department_id' => $dept_id));
				// $data['leave_info'] 	   = $this->model_leave->getLeaveInfoStaffs($dept_id, $year);
				$data['leave_info'] 	   = $this->model_leave->getLeaveInfo(array('department_id = ' => $dept_id, 'year(date_from) = ' => $year, 'is_delete = ' => 0));
				if($mode=='debug') echo $this->db->last_query(); 
				
				$data['approve_persons']   = $this->model_leave->getApprovePerson($dept_id);
				$data['applications'] 	   = $this->model_leave->getApplication(array('i.department_id' => $dept_id, 'year(a.date_from)' => $year));
				// $data['applications'] 	   = $this->model_leave->getApplication(array('i.department_id' => $dept_id, 'j.parent_id >' => 2, 'year(a.date_from)' => $year));
				$data['relief_persons']    = $this->model_user->getUsersByFilter(array('d.department_id' => $data['department']['id']));
				$data['exam_list_all']		= $this->model_exam->get_exam_list();
				$data['page_setup'] = $this->template->pageSetup('HR', '', $year.' Department Leave ['.$data['department']['name'].']');
				$this->template->view('hr/leave/departmentsApplicationList', $data);
			}
		
		} else {
			if(strtolower($this->logged_module['role']) == 'user') 		redirect(base_url('hr/leave/'));
			if(strtolower($this->logged_module['role']) == 'moderator') redirect(base_url('hr/leave/department/'.$this->logged_user['department_id']));
			
			$data['departments'] = $this->model_company->getDepartments();
			
			$data['page_setup'] = $this->template->pageSetup('HR', '', 'Department List');
			$this->template->view('hr/leave/departmentsList', $data);
		}
		/*
		// if (strtolower($this->logged_module['role']) == 'admin') {
		// 	if($dept_id) {
		// 		if ($mode == 'print') {
					
		// 		} else {
		// 			$data['department'] 	   = $this->model_company->getDepartments(null, $dept_id);
		// 			$data['staffs']			   = $this->model_user->getUsersByFilter(array('d.department_id' => $dept_id));
		// 			$data['leave_info'] 	   = $this->model_leave->getLeaveInfoStaffs($dept_id, $year);
		// 			$data['approve_persons']   = $this->model_leave->getApprovePerson($dept_id);
		// 			$data['applications'] 	   = $this->model_leave->getApplication(array('i.department_id' => $dept_id, 'j.parent_id >' => 2, 'year(a.date_from)' => $year));
		// 			$data['relief_persons']    = $this->model_user->getUsersByFilter(array('d.department_id' => $data['department']['id']));

		// 			$data['page_setup'] = $this->template->pageSetup('HR', '', $year.' Department Leave ['.$data['department']['name'].']');
		// 			$this->template->view('hr/leave/departmentsApplicationList', $data);
		// 		}
			
		// 	} else {
		// 		if(strtolower($this->logged_module['role']) != 'admin') redirect(base_url('hr/leave'));

		// 		$data['departments'] = $this->model_company->getDepartments();
				
		// 		$data['page_setup'] = $this->template->pageSetup('HR', '', 'Department List');
		// 		$this->template->view('hr/leave/departmentsList', $data);
		// 	}

		// } elseif (strtolower($this->logged_module['role']) == 'moderator') {
		// 	$data['department'] 	 = $this->model_company->getDepartments(null, $this->logged_user['department_id']);
		// 	$data['staffs']			 = $this->model_user->getUsersByFilter(array('d.department_id' => $this->logged_user['department_id']));
		// 	$data['leave_info'] 	 = $this->model_leave->getLeaveInfo(array('department_id' => $this->logged_user['department_id']));
		// 	$data['approve_persons'] = $this->model_leave->getApprovePerson($this->logged_user['department_id']);
		// 	$data['applications'] 	 = $this->model_leave->getApplication(array('i.department_id' => $this->logged_user['department_id'], 'j.parent_id >' => 2, 'year(a.date_from)' => $year));
		// 	$data['relief_persons']  = $this->model_user->getUsersByFilter(array('d.department_id' => $this->logged_user['department_id'], 'a.id !=' => $this->logged_user['id']));

		// 	$data['page_setup'] = $this->template->pageSetup('HR', '', 'Department Leave ['.$data['department']['name'].']');
		// 	$this->template->view('hr/leave/departmentsApplicationList', $data);

		// } else {
		// 	redirect(base_url('hr/leave'));
		// }  */
	}

	function admin_manager($year=null, $mode='default') {
		if (strtolower($this->logged_module['role']) == 'admin') {
			$year 	 	  	   = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
			$data['curr_year'] = $year;
			$data['years'] 	   = $this->model_leave->getEntitlementYears();
			

			if($mode == 'print') {
				$print_data = array(
					'title'   => 'MANAGER\'S LEAVE APPLICATION LIST REPORT FOR THE YEAR '.$year,
					'headers' => array('Applicant', 'Date From', 'Date To', 'Days', 'Leave Type', 'Status', 'Relief Person'),
					'body' 	  => $this->model_leave->getApplication(array('j.parent_id <' => 3, 'year(a.date_from)' => $year), null, 'print'),
				);

				$this->report_template($print_data);
			} else {
				$data['leave_info']    = $this->model_leave->getLeaveInfoManagers(array('year(date_from)' => $year));
				$data['leave_types']   = $this->model_leave->getLeaveType();
				$data['staffs'] 	   = $this->model_user->getUsersByFilter(array('e.parent_id <' => 3)); 
				$data['applications']  = $this->model_leave->getApplication(array('j.parent_id <' => 3, 'year(a.date_from)' => $year));
				$data['leave_periods'] = $this->model_leave->getRefPeriod();
				$data['relief_persons']    = $this->model_user->getUsersByFilter();
				$data['exam_list_all'] = $this->model_exam->get_exam_list();
				$data['page_setup'] = $this->template->pageSetup('HR', '', 'Manager\'s Leave');
				$this->template->view('hr/leave/managersApplicationList', $data);
			}
		} else {
			redirect(base_url('hr/leave'));
		}
	}

	private function report_template($data) {
        $header = array('title' => $data['title']);

        $body = array(
            'table' => array(
                'header' => $data['headers'],
                'body'   => $data['body']
            )
        );

        $this->load->view('leave/report/header', $header);
        if (isset($data['detail'])) {
            
        }

        $this->load->view('leave/report/body', $body);
        $this->load->view('leave/report/footer');
    }

	// Returns true / false
	function checkProRate($user_id, $date_from, $date_to) {
		$prorate = $this->getProRate($user_id, $date_from->format('Y-m-d'));
		if ($prorate) {
			$days_applied = $this->countDays($date_from, $date_to);

			if ($prorate['allowed_leave'] >= $days_applied) {
				return array('status' => true, 'prorate' => $prorate);
			} else {
				$unpaid_applied = $days_applied - $prorate['allowed_leave'];

				return array(
					'status' 		 => false,
					'unpaid_applied' => $unpaid_applied,
					'prorate' 		 => $prorate
				);
			}
		}
	}

	// Returns calculation data
	function getProRate_old($user_id, $leave_date=null,$mode='default') {
		$user 			   = $this->model_user->getUsers($user_id);
		$today		 	   = new DateTime(date('Y-m-d'));
		$new_year 		   = new DateTime(date('Y-01-01'));
		$date_joined 	   = new DateTime($user['date_joined']);
		$date_commencement = new DateTime($user['date_commencement']);

		if($mode=='debug')	{ 
			echo '<br>get prorate from date commencement <br>'.$this->db->last_query();
				var_dump($date_commencement);
		}

		if ($leave_date) $leave_date = new DateTime(date($leave_date));

		$AL = $this->model_leave->getAllocation_currentYear(array(
			'a.user_id' => $user_id, 
			'a.year'    => ($leave_date) ? $leave_date->format('Y') : $today->format('Y'), 
			'a.type_id' => 1
		));
		if($mode=='debug')	{
			echo '<br>function getProRate:get allocation (query ni slow): '.$this->db->last_query();
			var_dump($AL);
			echo '<br> user : <br>';
			var_dump($user);
		}

		if ($AL) {
			if (($user['position_id'] == 21 && $user['contract_term'] < 12) && $date_commencement->format('Y') == $today->format('Y')) {
				$prorate['month_of_service'] = ($leave_date) ? $date_commencement->diff($leave_date)->m + 1 : $date_commencement->diff($today)->m + 1;
				$prorate['monthly']			 = ($user['contract_term']) ? (float) $AL['leave_entitled'] / $user['contract_term'] : (float) $AL['leave_entitled'] / 12;
				$prorate['formula'] = 1; 
			} else if ($date_commencement->format('Y') == $today->format('Y') && $date_joined->format('Y') == $date_commencement->format('Y')) {
				/*** akmal 20191112 formula utk sapa yg naik pangkat, kena guna date joined **/				
				$prorate['month_of_service'] = ($leave_date) ? $date_commencement->diff($leave_date)->m + 1 : $date_commencement->diff($today)->m + 1;
				$prorate['monthly']			 = (float) $AL['leave_entitled'] / 12;
				$prorate['formula'] = 2; 
			} else {
				$prorate['month_of_service'] = ($leave_date) ? $new_year->diff($leave_date)->m + 1 : $new_year->diff($today)->m + 1; //11
				$prorate['monthly'] 		 = (float) $AL['leave_entitled'] / 12;
				$prorate['formula'] = 3; 
			}

			if (isset($prorate)) {
				// $prorate['past_applications'] = ($leave_date) ? $this->model_leave->getLeaveUntilMonth($user['id'], $leave_date->format('Y-m-d')) : $this->model_leave->getLeaveUntilMonth($user['id'], $today->format('Y-m-d'));
				
				$prorate['past_applications'] = ($leave_date) ? $this->model_leave->getLeaveForTheYear($user['id'], $leave_date->format('Y')) : $this->model_leave->getLeaveForTheYear($user['id'], $today->format('Y'));
				$prorate['current'] 		  = $prorate['monthly'] * $prorate['month_of_service'];

				if($mode=='debug')	{
					echo '<br>prorate formula = '.$prorate['formula'].'<br>' ;
					echo '<br>prorate monthly = '.$prorate['monthly'].'<br>' ;
					echo ($leave_date)?'<br>month of service 1 = '. $date_commencement->diff($leave_date)->m .'+ 1 ':
					'<br>month of service 2 = '. $date_commencement->diff($today)->m .'+ 1'; 
					echo $this->db->last_query();
					echo '<br>current => prorate x month of service iaitu '.$prorate['current'] .' = '.$prorate['monthly'].' * '. $prorate['month_of_service'];
				}

				$prorate['leave_to_date'] 	  = 0;
				$prorate['leave_this_month']  = 0;
				
				/*akmal 20190925 to calculate leave taken from bring forward */
				$bring_forward_balance = $AL['bring_forward_entitled'];
				$taken_from_bring_forward = 0; 
					
				if(isset($prorate['past_applications'])) {					
					foreach($prorate['past_applications'] as $application) {
						$date_from = new DateTime($application->date_from);
						if($date_from->format('m') < 4 && $bring_forward_balance > 0) { //if leave taken before april
							if($bring_forward_balance >= floatval($application->days_applied)){
								$bring_forward_balance -= floatval($application->days_applied);
								$taken_from_bring_forward += floatval($application->days_applied);
							}else {
								$temp = floatval($application->days_applied) - floatval($bring_forward_balance); 
								$bring_forward_balance -= floatval($temp);
								$taken_from_bring_forward += floatval($temp);
							}
						} //	echo '<br>'.$prorate['leave_to_date'].' += '.floatval($application->days_applied);
						$prorate['leave_to_date'] += floatval($application->days_applied);
						if ($today->format('Y-m') == $date_from->format('Y-m')) $prorate['leave_this_month'] += floatval($application->days_applied);
					}
				}
				
				//$prorate['taken_bring_forward'] = $AL['bring_forward_entitled'] - $AL['bring_forward'];
				$prorate['taken_bring_forward'] = $taken_from_bring_forward; 

				if($mode=='debug')	{ 
					echo $this->db->last_query();
					echo '<br>$prorate["taken_annual"] = '.$prorate['leave_to_date'] .' - '. $prorate['taken_bring_forward'];
				}
				
				$prorate['taken_annual'] 		= $prorate['leave_to_date'] - $prorate['taken_bring_forward'];

				$prorate['allowed_bring_forward'] = ( ($leave_date) ? $leave_date->format('m') < '4' : $today->format('m') < '4') ? $AL['bring_forward_entitled'] : 0; 
				//$prorate['allowed_bring_forward'] = ( ($leave_date) ? $leave_date->format('m') < '4' : $today->format('m') < '4') ? $AL['bring_forward'] : 0;

				if($mode=='debug')	{
				//echo $this->db->last_query();
					echo '<br>$prorate["allowed_annual"] =>'.	$prorate['current'] .' - '. $prorate['taken_annual'].' = '; 
				}
				
				//	echo '<br>$prorate["allowed_annual"] ='.	$prorate['current'] .' - '. $prorate['taken_annual'].' = '; 						
				$prorate['allowed_annual'] 		  = $prorate['current'] - $prorate['taken_annual'];
				//	echo $prorate['allowed_annual'];			
				// $prorate['allowed_annual'] 				= (float) round($prorate['allowed_annual'] * 2) / 2;
				//	echo '<br>$prorate["allowed_leave"] ='.	$prorate['allowed_bring_forward'] .' + '. $prorate['allowed_annual'];		
				$prorate['allowed_leave'] 		  = $prorate['allowed_bring_forward'] + $prorate['allowed_annual'];
				// $prorate['allowed_leave'] 		  = (float) ($prorate['allowed_leave'] < $AL['leave_balance']) ? $prorate['allowed_leave'] : $AL['leave_balance'];

				if ($prorate['allowed_leave'] < 0) $prorate['allowed_leave'] = 0;
			}

			//if($mode=='debug')	var_dump($prorate['formula'] ;);

			return $prorate;

		}
	}

	function validateDate($date, $format = 'Y-m-d H:i:s')
	{
		$d = DateTime::createFromFormat($format, $date);
		return $d && $d->format($format) == $date;
	}

	/**
	 * @api
	 */
	function sendAllocationRequest()	{
		$data = $this->input->post();

		if(isset($data['leave_type_id'])) {
			/**
			 * @todo Send request to admin and email
			 */
		} else {
			/**
			 * @todo Reject
			 */
		}
	}

	function getEntitlementsForClone() {
		$data = $this->input->post();

		// die(debug($data));
	}

	function countBringForward() {
		$allocation  = $this->model_leave->getAllocation(array('a.user_id' => $data['user_id'], 'a.year' => $data['year'] - 1, 'a.type_id' => 1));
		$entitlement = $this->model_leave->getEntitlement(array('a.year' => $data['year'], 'a.type_id' => 1, 'a.category_id' => $data['category_id']));

		if ($allocation && $entitlement) {
			$allowed_bring_forward = floatval($allocation['leave_entitled']) * (floatval($entitlement['bring_forward_percentage']) / 100);
			$bring_forward 		   = (floatval($allocation['leave_balance']) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($allocation['leave_balance']);
		}
	}

	function AJAX_getBringForward() {
		$data = $this->input->get();

		if ($data) {
			$allocation  = $this->model_leave->getAllocation(array('a.user_id' => $data['user_id'], 'a.year' => $data['year'] - 1, 'a.type_id' => 1));
			$entitlement = $this->model_leave->getEntitlement(array('a.year' => $data['year'], 'a.type_id' => 1, 'a.category_id' => $data['category_id']));
			if ($allocation && $entitlement) {
				$allowed_bring_forward = floatval($allocation['leave_entitled']) * (floatval($entitlement['bring_forward_percentage']) / 100);
				$bring_forward 		   = (floatval($allocation['leave_balance']) > $allowed_bring_forward) ? $allowed_bring_forward : floatval($allocation['leave_balance']);

				print json_encode(array(
					"status" => "success",
					"bring_forward" => array(
						"leave_entitled" 		   => floatval($allocation['leave_entitled']),
						"bring_forward_percentage" => floatval($entitlement['bring_forward_percentage']) / 100,
						"leave_balance" 		   => floatval($allocation['leave_balance']),
						"allowed_bring_forward"    => $allowed_bring_forward,
						"bring_forward" 		   => $bring_forward
					)
				));
			} else {
				if (!$allocation) {
					print json_encode(array(
						"status"  => "error",
						"message" => "Previous year allocation is missing."
					));
				}
				 
				if (!$entitlement) {
					print json_encode(array(
						"status"  => "error",
						"message" => "Current year entitlement is missing."
					));
				}
			}
		}
	}

	function AJAX_getAdditionalLeave() {
		// if staff profiling is done, change date joined to date commencement, signifying that additional leave increment will be reset if user is promoted

		$data = $this->input->get();

		if ($data) {
			$user 		 = $this->model_user->getUsers($data['user_id']);
			$entitlement = $this->model_leave->getEntitlement(array('a.year' => $data['year'], 'a.type_id' => 1, 'a.category_id' => $data['category_id']));
			$allocation  = $this->model_leave->getAllocation(array('a.user_id' => $data['user_id'], 'a.year' => $data['year'] - 1, 'a.type_id' => 1));
			
			if($allocation['balance_entitled']) {
				$balance_entitled 	  = floatval($allocation['balance_entitled']);
				$month_cycle 	  	  = floatval($entitlement['month_of_service_add_leave']);
				$additional_leave 	  = floatval($entitlement['additional_leave']);
				$max_additional_leave = floatval($entitlement['max_entitlement']) - floatval($entitlement['entitled_leave']);

				$cycle_dates = array();
				$past_dates  = array();

				$joined_date = DateTime::createFromFormat('Y-m-d', $user['date_joined']);
				$setup_date  = DateTime::createFromFormat('Y-m-d', $data['year'].'-01-01');

				$total_count_months = $joined_date->diff($setup_date)->m + ($joined_date->diff($setup_date)->y*12);

				for ($i=1; $i <= $max_additional_leave; $i++) { 
					$intervals = date_interval_create_from_date_string($month_cycle.' months');
					$date = date_add($joined_date, $intervals);
					array_push($cycle_dates, date_format($date, 'Y-m-d'));

					if ($date < $setup_date) array_push($past_dates, date_format($date, 'Y-m-d'));
				}

				if (empty($past_dates)) {
					$count_months = $total_count_months;
				} else {
					$last_increment_date = date_create(end($past_dates));
					$count_months = $last_increment_date->diff($setup_date)->m + ($last_increment_date->diff($setup_date)->y*12);
				}

				if ($count_months >= $month_cycle) $balance_entitled = (($balance_entitled + $additional_leave) <= floatval($entitlement['max_entitlement'])) ? $balance_entitled + $additional_leave : $balance_entitled;

				$total_additional_leave = (($balance_entitled - floatval($entitlement['entitled_leave'])) > 0) ? $balance_entitled - floatval($entitlement['entitled_leave']) : 0;
				$leave_allocation = floatval($entitlement['entitled_leave']) + $total_additional_leave;
				
				print json_encode(array(
					"status"     	   => "success",
					"additional_leave" => array(
						"year"			   		 => $data['year'],
						"date_joined" 	   		 => $user['date_joined'],
						"total_count_months" 	 => $total_count_months,
						"count_months_from_last" => $count_months,
						"previous_allocation" 	 => floatval($allocation['balance_entitled']),
						"leave_allocation" 		 => $leave_allocation,
						"month_cycle" 	   		 => $month_cycle,
						"additional_leave" 		 => $additional_leave,
						"total_additional_leave" => $total_additional_leave,
						"cycle_dates"			 => $cycle_dates,
						"past_dates"			 => $past_dates
					)
				));
			}
		}
	}

	function countAdditionalLeave($user_id, $year) {
		$user 		 = $this->model_user->getUsers($user_id);
		$entitlement = $this->model_leave->getEntitlement(array('a.year' => $year, 'a.type_id' => 1, 'a.category_id' => $user['position_category_id']));
		$allocation  = $this->model_leave->getAllocation(array('a.user_id' => $user_id, 'a.year' => $year - 1, 'a.type_id' => 1));
		
		if($user['date_joined'] && $allocation['balance_entitled']) {
			$balance_entitled 	  = floatval($allocation['balance_entitled']);
			$month_cycle 	  	  = floatval($entitlement['month_of_service_add_leave']);
			$additional_leave 	  = floatval($entitlement['additional_leave']);
			$max_additional_leave = floatval($entitlement['max_entitlement']) - floatval($entitlement['entitled_leave']);

			$cycle_dates = array();
			$past_dates  = array();

			$joined_date = DateTime::createFromFormat('Y-m-d', $user['date_joined']);
			$setup_date  = DateTime::createFromFormat('Y-m-d', $year.'-01-01');

			$total_count_months = $joined_date->diff($setup_date)->m + ($joined_date->diff($setup_date)->y*12);

			for ($i=1; $i <= $max_additional_leave; $i++) { 
				$intervals = date_interval_create_from_date_string($month_cycle.' months');
				$date = date_add($joined_date, $intervals);
				array_push($cycle_dates, date_format($date, 'Y-m-d'));

				if ($date < $setup_date) array_push($past_dates, date_format($date, 'Y-m-d'));
			}

			if (empty($past_dates)) {
				$count_months = $total_count_months;
			} else {
				$last_increment_date = date_create(end($past_dates));
				$count_months = $last_increment_date->diff($setup_date)->m + ($last_increment_date->diff($setup_date)->y*12);
			}

			if ($count_months >= $month_cycle) $balance_entitled = (($balance_entitled + $additional_leave) <= floatval($entitlement['max_entitlement'])) ? $balance_entitled + $additional_leave : $balance_entitled;

			$total_additional_leave = (($balance_entitled - floatval($entitlement['entitled_leave'])) > 0) ? $balance_entitled - floatval($entitlement['entitled_leave']) : 0;
			$leave_allocation = floatval($entitlement['entitled_leave']) + $total_additional_leave;

			$return_data = array(
				"year"			   		 => $year,
				"date_joined" 	   		 => $user['date_joined'],
				"total_count_months" 	 => $total_count_months,
				"count_months_from_last" => $count_months,
				"previous_allocation" 	 => floatval($allocation['balance_entitled']),
				"leave_allocation" 		 => $leave_allocation,
				"month_cycle" 	   		 => $month_cycle,
				"additional_leave" 		 => $additional_leave,
				"total_additional_leave" => $total_additional_leave,
				"cycle_dates"			 => $cycle_dates,
				"past_dates"			 => $past_dates
			);

			return $return_data;
		} else {
			return array(
				"total_additional_leave" => 0
			);
		}
	}

	function countAdditionalLeave2($user_id, $year) {
		$year 	 	 		  = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		$user 		 		  = $this->model_user->getUsers($user_id);
		$entitlement 		  = $this->model_leave->getEntitlement(array('a.year' => $year, 'a.type_id' => 1, 'a.category_id' => $user['position_category_id']));
		$max_additional_leave = floatval($entitlement['max_entitlement']) - floatval($entitlement['entitled_leave']);
		// $allocation  = $this->model_leave->getAllocation(array('a.user_id' => $user_id, 'a.year' => $year - 1, 'a.type_id' => 1));

		$current_date 		 = strtotime(date($year.'-01-01'));
		$joined_date  		 = strtotime($user['date_joined']);
		$new_policy_date 	 = strtotime('first day of January 2018');
		$total_count_months  = $this->countMonths($joined_date, $current_date);
		$og_additional_leave = 2;
		
		if ($joined_date < $new_policy_date) {
			$count_months_og 		= $this->countMonths($joined_date, $new_policy_date);
			$og_multiplier 			= floor($count_months_og / 24);
			$og_balance 			= $count_months_og % 24;
			$count_months_og 		= $count_months_og - $og_balance;
			$additional_leave_og 	= $og_multiplier * $og_additional_leave;
			$count_months_new 		= $this->countMonths($new_policy_date, $current_date);
			$count_months_new 		= $count_months_new + $og_balance;
			$new_mulitplier 		= floor($count_months_new / floatval($entitlement['month_of_service_add_leave']));
			$additional_leave_new 	= ($new_mulitplier >= 1) ? $new_mulitplier * floatval($entitlement['additional_leave']) : 0;
			$additional_leave 		= $additional_leave_og + $additional_leave_new;

		} else {
			$min_date = min($current_date, $joined_date);
			$max_date = max($current_date, $joined_date);

			$count_months_new = 0;

			while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
				$count_months_new++;
			}

			$multiplier 		  = ($count_months_new > 0 && $entitlement['month_of_service_add_leave'] > 0) ? floor($count_months_new / floatval($entitlement['month_of_service_add_leave'])) : 0;
			$additional_leave 	  = ($multiplier >= 1) ? $multiplier * floatval($entitlement['additional_leave']) : 0;
			$additional_leave_new = $additional_leave;
		}

		$additional_leave = ($additional_leave <= $max_additional_leave) ? $additional_leave : $max_additional_leave;

		if(isset($additional_leave)) {
			return array(
				"date_joined" 					 => $user['date_joined'],
				"total_count_months" 			 => $total_count_months,
				"count_months_old" 				 => (isset($count_months_og)) ? $count_months_og : 0,
				"count_months_new" 				 => $count_months_new,
				"additional_leave_increment_old" => (isset($og_additional_leave)) ? $og_additional_leave : 0,
				"additional_leave_increment_new" => floatval($entitlement['additional_leave']),
				"total_additional_leave_old" 	 => (isset($additional_leave_og)) ? $additional_leave_og : 0,
				"total_additional_leave_new" 	 => $additional_leave_new,
				"month_cycle" 					 => floatval($entitlement['month_of_service_add_leave']),
				"max_additional_leave"			 => $max_additional_leave,
				"total_additional_leave" 		 => $additional_leave,

			);
		} else {
			return array(
				"total_additional_leave" => 0
			);
		}
	}

//akmal 20191206 countAdditionalLeave3 has an error where additional leave = 0 in third year. 
	function countAdditionalLeave3($year, $user = array(), $entitlement= array()) {
		$year 	 	 		  = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		$current_date 		  = strtotime(date($year.'-01-01'));
		$joined_date  		  = strtotime($user['date_joined']);
		$new_policy_date 	  = strtotime('first day of January 2018');
		$total_count_months   = $this->countMonths($joined_date, $current_date);
		$og_additional_leave  = 2;
		$max_additional_leave = floatval($entitlement['max_entitlement']) - floatval($entitlement['entitled_leave']);

		if($joined_date) {
			if ($joined_date < $new_policy_date) {
				$count_months_og 		= $this->countMonths($joined_date, $new_policy_date);
				$og_multiplier 			= floor($count_months_og / 24);
				$og_balance 			= $count_months_og % 24;
				$count_months_og 		= $count_months_og - $og_balance;
				$additional_leave_og 	= $og_multiplier * $og_additional_leave;
				$count_months_new 		= $this->countMonths($new_policy_date, $current_date);
				$count_months_new 		= $count_months_new + $og_balance;
				$new_mulitplier 		= ($count_months_new > 0 && $entitlement['month_of_service_add_leave']) ? floor($count_months_new / floatval($entitlement['month_of_service_add_leave'])) : 0;
				$additional_leave_new 	= ($new_mulitplier >= 1) ? $new_mulitplier * floatval($entitlement['additional_leave']) : 0;
				$additional_leave 		= $additional_leave_og + $additional_leave_new;

			} else {
				$min_date = min($current_date, $joined_date);
				$max_date = max($current_date, $joined_date);

				$count_months_new = 0;

				while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
					$count_months_new++;
				}

				$multiplier 		  = ($count_months_new > 0 && $entitlement['month_of_service_add_leave'] > 0) ? floor($count_months_new / floatval($entitlement['month_of_service_add_leave'])) : 0;
				$additional_leave 	  = ($multiplier >= 1) ? $multiplier * floatval($entitlement['additional_leave']) : 0;
				$additional_leave_new = $additional_leave;
			}

			$additional_leave = ($additional_leave <= $max_additional_leave) ? $additional_leave : $max_additional_leave;

			if(isset($additional_leave)) {
				return array(
					"date_joined" 					 => $user['date_joined'],
					"total_count_months" 			 => $total_count_months,
					"count_months_old" 				 => (isset($count_months_og)) ? $count_months_og : 0,
					"count_months_new" 				 => $count_months_new,
					"additional_leave_increment_old" => (isset($og_additional_leave)) ? $og_additional_leave : 0,
					"additional_leave_increment_new" => 1,
					"total_additional_leave_old" 	 => (isset($additional_leave_og)) ? $additional_leave_og : 0,
					"total_additional_leave_new" 	 => $additional_leave_new,
					"month_cycle" 					 => floatval($entitlement['month_of_service_add_leave']),
					"max_additional_leave"			 => $max_additional_leave,
					"total_additional_leave" 		 => $additional_leave,

				);
			} else {
				return array(
					"total_additional_leave" => 0
				);
			}
		} else {
			return array(
				"total_additional_leave" => 0
			);
		}
	}

/* //akmal 20191206 countAdditionalLeave4. to replace countAdditionalLeave3. 
//method to count additional leave. look back the allocation for year - 2 or month - 24. 
//additional leave =  (last.allocation < enttilement)?0:addional leave.  
//if(allocation for last 2 years is null or < current entitlement) {
//this is new staff, so no additional leave. 
//}else{old staff need to add additional_leave */ 
	function countAdditionalLeave4($year, $user = array(), $entitlement= array()) {
		$year 	 	 		  = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		$current_date 		  = strtotime(date($year.'-01-01'));
		$joined_date  		  = strtotime($user['date_joined']);
		$new_policy_date 	  = strtotime('first day of January 2018');
		$total_count_months   = $this->countMonths($joined_date, $current_date);
		$og_additional_leave  = 2;
		$max_additional_leave = floatval($entitlement['max_entitlement']) - floatval($entitlement['entitled_leave']);
		
		if($joined_date) {
			if ($joined_date < $new_policy_date) {
				$count_months_og 		= $this->countMonths($joined_date, $new_policy_date);
				$og_multiplier 			= floor($count_months_og / 24);
				$og_balance 			= $count_months_og % 24;
				$count_months_og 		= $count_months_og - $og_balance;
				$additional_leave_og 	= $og_multiplier * $og_additional_leave;
				$count_months_new 		= $this->countMonths($new_policy_date, $current_date);
				$count_months_new 		= $count_months_new + $og_balance;
				$new_mulitplier 		= ($count_months_new > 0 && $entitlement['month_of_service_add_leave']) ? floor($count_months_new / floatval($entitlement['month_of_service_add_leave'])) : 0;
				$additional_leave_new 	= ($new_mulitplier >= 1) ? $new_mulitplier * floatval($entitlement['additional_leave']) : 0;
				$additional_leave 		= $additional_leave_og + $additional_leave_new;

			} else {
				$min_date = min($current_date, $joined_date);
				$max_date = max($current_date, $joined_date);

				$count_months_new = 0;

				while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
					$count_months_new++;
				}

				$multiplier 		  = ($count_months_new > 0 && $entitlement['month_of_service_add_leave'] > 0) ? floor($count_months_new / floatval($entitlement['month_of_service_add_leave'])) : 0;
				$additional_leave 	  = ($multiplier >= 1) ? $multiplier * floatval($entitlement['additional_leave']) : 0;
				$additional_leave_new = $additional_leave;
			}

			$additional_leave = ($additional_leave <= $max_additional_leave) ? $additional_leave : $max_additional_leave;

			if(isset($additional_leave)) {
				return array(
					"date_joined" 					 => $user['date_joined'],
					"total_count_months" 			 => $total_count_months,
					"count_months_old" 				 => (isset($count_months_og)) ? $count_months_og : 0,
					"count_months_new" 				 => $count_months_new,
					"additional_leave_increment_old" => (isset($og_additional_leave)) ? $og_additional_leave : 0,
					"additional_leave_increment_new" => 1,
					"total_additional_leave_old" 	 => (isset($additional_leave_og)) ? $additional_leave_og : 0,
					"total_additional_leave_new" 	 => $additional_leave_new,
					"month_cycle" 					 => floatval($entitlement['month_of_service_add_leave']),
					"max_additional_leave"			 => $max_additional_leave,
					"total_additional_leave" 		 => $additional_leave,

				);
			} else {
				return array(
					"total_additional_leave" => 0
				);
			}
		} else {
			return array(
				"total_additional_leave" => 0
			);
		}
	}

/*	// function getAdditionalLeave() {
	// 	$data = $this->input->get();

	// 	if ($data) {
	// 		$user = $this->model_user->getUsers($data['user_id']);
	// 		$entitlement = $this->model_leave->getEntitlement(array('a.year' => $data['year'], 'a.type_id' => 1, 'a.category_id' => $data['category_id']));
	// 		$allocation = $this->model_leave->getAllocation(array('a.user_id' => $data['user_id'], 'a.year' => $data['year'] - 1, 'a.type_id' => 1));

	// 		if($allocation['balance_entitled']) {
	// 			$current_date = strtotime(date('Y-m-d'));
	// 			$joined_date  = strtotime($user['date_joined']);
	// 			$new_policy_date = strtotime('first day of January 2018');
				
	// 			if ($joined_date < $new_policy_date) {
	// 				$total_count_months 	= $this->countMonths($joined_date, $current_date);

	// 				$og_additional_leave 	= 2;
	// 				$count_months_og 		= $this->countMonths($joined_date, $new_policy_date);
	// 				$og_multiplier 			= floor($count_months_og / 24);
	// 				$og_balance 			= $count_months_og % 24;
	// 				$count_months_og 		= $count_months_og - $og_balance;
	// 				$additional_leave_og 	= $og_multiplier * $og_additional_leave;

	// 				$count_months_new 		= $this->countMonths($new_policy_date, $current_date);
	// 				$count_months_new 		= $count_months_new + $og_balance;
	// 				$new_mulitplier 		= floor($count_months_new / floatval($entitlement['month_of_service_add_leave']));
	// 				$additional_leave_new 	= ($new_mulitplier >= 1) ? $new_mulitplier * floatval($entitlement['additional_leave']) : 0;

	// 				$additional_leave 		= $additional_leave_og + $additional_leave_new;
	// 			} else {
	// 				$min_date = min($current_date, $joined_date);
	// 				$max_date = max($current_date, $joined_date);

	// 				$count_months = 0;

	// 				while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
	// 					$count_months++;
	// 				}

	// 				$multiplier = floor($count_months / floatval($entitlement['month_of_service_add_leave']));
	// 				$additional_leave = ($multiplier >= 1) ? $multiplier * floatval($entitlement['additional_leave']) : 0;
	// 			}
	
	// 			if(isset($additional_leave)) {
	// 				print json_encode(array(
	// 					"status"     	   => "success",
	// 					"additional_leave" => array(
	// 						"date_joined" => $user['date_joined'],
	// 						"total_count_months" =>$total_count_months,
	// 						"count_months_old" => $count_months_og,
	// 						"count_months_new" => $count_months_new,
	// 						"additional_leave_increment_old" => $og_additional_leave,
	// 						"additional_leave_increment_new" => floatval($entitlement['additional_leave']),
	// 						"total_additional_leave_old" => $additional_leave_og,
	// 						"total_additional_leave_new" => $additional_leave_new,
	// 						"month_cycle" => floatval($entitlement['month_of_service_add_leave']),
	// 						"total_additional_leave" => $additional_leave
	// 					)
	// 				));
	// 			} else {
	// 				print json_encode(array(
	// 					"status" 	=> "error"
	// 				));
	// 			}
	// 		}
	// 	}
	// } */

	function countMonths($date_from, $date_to) {
		// $start = date('Y-m-d', strtotime($date_from));
		// $end = date('Y-m-d', strtotime($date_to));

		$min_date = min($date_to, $date_from);
		$max_date = max($date_to, $date_from);

		$count_months = 0;

		while (($min_date = strtotime("+1 MONTH", $min_date)) <= $max_date) {
			$count_months++;
		}

		return $count_months;
	}


	private function upload($type, $file, $file_location){
		$fcpath = str_replace('\\','/',FCPATH);
		$dir = str_replace('\\','/',$fcpath.'assets/uploads/'.$file_location);
		$dir = str_replace('\\','/',$dir);
		
		$file_name = str_replace(' ', '_', trim(addslashes(substr($_FILES[$file]['name'],-50))));
		$file_name = time().'_'.$file_name;
		$url = NULL;

		(!file_exists($dir))?mkdir($dir, 0777, true):chmod($dir, 0777);

		if (is_uploaded_file($_FILES[$file]['tmp_name']))
		{
			if($type == 'document') $file_types = 'pdf|doc|docx';
			if($type == 'image') $file_types = 'jpg|jpeg|bmp|png|gif|svg|ico';
			if($type == 'attachment') $file_types = 'pdf|doc|docx|jpg|jpeg|bmp|png|gif|svg|ico';

			$config = array(
				'allowed_types' => $file_types,
				'upload_path' => $dir,
				'file_name' => $file_name,
				'max_size' => 0,
				'overwrite' => TRUE
			);

			$this->load->library('upload', $config);

			if ($this->upload->do_upload($file))
			{
				if($upload_data = $this->upload->data())
				{
					if($type=="image")
					{
						// GET WIDTH & HEIGHT TO RESIZE & CROP
						$oriWidth  = (isset($upload_data['image_width']) > 0) ? $upload_data['image_width'] : 1; // ORIGINAL WIDTH
						$oriHeight = $upload_data['image_height'];											     // ORIGINAL HEIGHT
						$resWidth  = floor(($oriWidth > 500) ? 500 : $oriWidth); 							     // WIDTH TO RESIZE
						$resHeight = floor(($resWidth/$oriWidth)*$oriHeight); 								     // HEIGHT TO RESIZE

						if ($resHeight > 500)
						{
							$resWidth = floor((500/$resHeight)*$resWidth);
							$resHeight = 500;
						}

						// MANIPULATION CONFIGURATION FOR RESIZING
						$manipulate['image_library']  = 'gd2';
						$manipulate['source_image']   = $upload_data['full_path'];
						$manipulate['maintain_ratio'] = TRUE;
						$manipulate['width']     	  = $resWidth;
						$manipulate['height']   	  = $resHeight;

						$this->load->library('image_lib', $manipulate);
						$this->image_lib->resize();
					}

					$data['file_name'] 	   = $upload_data['file_name'];
					$data['file_location'] = 'assets/uploads/'.$file_location;
				}
				else
				{
					if($type=="image")
					{
						$data['file_name'] 	   = 'default.png';
						$data['file_location'] = 'assets/uploads/defaults';
					}
				}
			}
			else
			{
				if($type=="image")
				{
					$data['file_name'] 	   = 'default.png';
					$data['file_location'] = 'assets/uploads/defaults';
				}
			}
		}

		return $data;
	}

	function updateApplication()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$date_from = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
			$date_to	 = new DateTime(date('Y-m-d', strtotime($data['date_to'])));

			$next_date_from = new DateTime(date('Y-m-d', strtotime('+1 day', strtotime($data['date_from']))));
			$prev_date_to = new DateTime(date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))));

			$half_day = 0.5;

			// COUNT DAYS APPLIED
			if($data['type_id'] == 5){ //maternity leave calculate include weekend
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDaysIncludeWeekend($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}else{
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDays($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDays($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}

			
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_application', $data, array('id'=>$id));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Application."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function deleteApplication()	{
		$data = $this->input->post();
		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_application', $data, array('id'=>$data['id']));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Application."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function approveApplication() {
		if(strtolower($this->logged_module['role']) == 'user') return false; 

		$id = $this->input->post('id');

		$remarks = ($this->input->post('remarks')) ? $this->input->post('remarks') : '';

		if ($id) {
			$application   = $this->model_leave->getApplication(array('a.id' => $id))[0];
			$date_from 	   = new DateTime(date($application['date_from']));
			$date_to	   = new DateTime(date($application['date_to']));
			$end_of_march  = new DateTime(date($date_from->format('Y').'-03-31'));
			$start_of_year = new DateTime(date($date_from->format('Y').'-01-01'));
			$end_of_year   = new DateTime(date($date_from->format('Y').'-12-31'));

			/**
			 * Annual Leave Allocation Date Rules:
			 * 
			 * 1 : Leave date is in the same year, start date and end date before 31st march
			 * 2 : Leave date is in the same year, start_date is before 31st march and end date is after 31st march
			 * 3 : Leave date is in the same year, start date and end date after 31st march
			 * 4 : Leave date is across years
			 * 
			 */

			$allocation = $this->model_leave->getAllocation(array(
				'a.user_id' => $application['user_id'], 
				'a.year' 	=> $date_from->format('Y'), 
				'a.type_id' => $application['type_id']
			));

			if ($application['type_id'] == 1) {  //AL
				$prorate = $this->checkProRate($application['user_id'], $date_from, $date_to);
				
				$date_rule = $this->checkLeaveDateRules($date_from, $date_to);

				switch ($date_rule) {
					// Leave date is in the same year, start date and end date before 31st march
//akmal 20200108 kesalahan dlm pengiraan leave_taken bring forward tak cukup 					
					case 1:
						// if bring forward balance is more than leave days applied
						if ($allocation['bring_forward'] >= $application['days_applied']) {
							$leave_applied 		   = 0;
							$bring_forward_applied = floatval($application['days_applied']);

							$data[$allocation['id']]['bring_forward'] = floatval($allocation['bring_forward']) - $bring_forward_applied;
							
						} else {
							$bring_forward_applied = $allocation['bring_forward'];

							$application['days_applied'] -= $bring_forward_applied;
							$leave_applied = $application['days_applied'];

							$data[$allocation['id']]['bring_forward'] = 0;
							$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) - $application['days_applied'];
						}
						
						$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) + $application['days_applied'];

						break;

					// Leave date is in the same year, start_date is before 31st march and end date is after 31st march
//akmal 20200108 kesalahan dlm pengiraan bring_forward dan leave balance bila bring forward tak cukup	
					case 2:
						$bring_forward_applied = floatval($this->countDays($date_from, $end_of_march));
						$leave_applied 		   = floatval($application['days_applied']) - $bring_forward_applied;

						$data[$allocation['id']]['bring_forward'] = floatval($allocation['bring_forward']) - $bring_forward_applied;
						$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) - $leave_applied;
						$data[$allocation['id']]['leave_taken']   = floatval($allocation['leave_taken']) + $application['days_applied'];
						
						break;

					// Leave date is in the same year, start date and end date after 31st march
//akmal 20200108 kesalahan dlm pengiraan jika balance tak cukup  					
					case 3:
						$leave_applied = floatval($application['days_applied']);

						$data[$allocation['id']]['leave_taken']   = floatval($allocation['leave_taken']) + $leave_applied;
						$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) - $leave_applied;

						break;

					// Leave date is across years
					case 4:
						$allocation_to = $this->model_leave->getAllocation(array(
							'a.user_id' => $application['user_id'], 
							'a.year' 	=> $date_to->format('Y'), 
							'a.type_id' => $application['type_id']
						));

						// if next year leave is allocated
						if ($allocation_to) {
							// get remaining leave days carried to next year
							$days_applied_from = $this->countDays($date_from, $end_of_year); // $leave_applied
							$days_applied_to 	= $application['days_applied'] - $days_applied_from;

							$leave_applied = floatval($days_applied_from);

							// allocation start year
							$data[$allocation['id']]['leave_taken']   = floatval($allocation['leave_taken']) + $days_applied_from;
							$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) - $data[$allocation['id']]['leave_taken'];

							// allocation end year
							$leave_applied_to = floatval($days_applied_to);
							if ($allocation_to['bring_forward'] >= $days_applied_to) {
								$bring_forward_applied_to = floatval($days_applied_to);
								$data[$allocation_to['id']]['bring_forward'] = floatval($allocation_to['bring_forward']) - $bring_forward_applied_to;
							} else {
								$bring_forward_applied_to = floatval($allocation_to['bring_forward']);
								$days_applied_to -= $bring_forward_applied_to;

								$data[$allocation_to['id']]['bring_forward'] = 0;
								$data[$allocation_to['id']]['leave_balance'] = floatval($allocation_to['leave_balance']) - $leave_applied_to;
							}

							$transactions[$allocation_to['id']]['leave_applied'] 		 = $leave_applied_to;
							$transactions[$allocation_to['id']]['bring_forward_applied'] = $bring_forward_applied_to;

						} else {
							print json_encode(array(
								"status" => "Error",
								"msg"	 => "Allocation for this leave type in the following year is not available. Please contact Administrator for further enquiries."
							));
						}
						
						break;
				}

				$transactions[$allocation['id']]['leave_applied'] 		  = (float) ( $leave_applied ) ? $leave_applied : 0;
				$transactions[$allocation['id']]['bring_forward_applied'] = (float) ( isset($bring_forward_applied) ) ? $bring_forward_applied : 0;
			
			} else if ($application['type_id'] == 2) {
				$annual_allocation = $this->model_leave->getAllocation(array(
					'a.user_id' => $application['user_id'], 
					'a.year' 		=> $date_from->format('Y'), 
					'a.type_id' => 1
				));

				$prorate = $this->checkProRate($application['user_id'], $date_from, $date_to);
				// Check if involved unpaid leave
				if ($prorate['status'] == false) {
					$unpaid_allocation = $this->model_leave->getAllocation(array(
						'a.user_id' => $application['user_id'], 
						'a.year' 	=> $date_from->format('Y'), 
						'a.type_id' => 4
					));
				}

				$date_rule = $this->checkLeaveDateRules($date_from, $date_to);

				switch ($date_rule) {
					// Leave date is in the same year, start date and end date before 31st march
					case 1:
						$bring_forward_applied = (float) ($application['days_applied'] > $annual_allocation['bring_forward']) ? $annual_allocation['bring_forward'] : $application['days_applied'];
						$leave_applied 	   	   = $application['days_applied'] - $bring_forward_applied;

						// DATA: Emergency Leave
						$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) + $application['days_applied'];

						// DATA: Annual Leave
						$data[$annual_allocation['id']]['bring_forward'] = floatval($annual_allocation['bring_forward']) - $bring_forward_applied;
						$data[$annual_allocation['id']]['leave_balance'] = floatval($annual_allocation['leave_balance']) - $leave_applied;
						// $data[$annual_allocation['id']]['leave_taken'] 	 = floatval($annual_allocation['leave_taken']) + $application['days_applied'];
						
						// DATA: Unpaid Leave
						// if ($prorate['status'] == false) $data[$unpaid_allocation['id']]['leave_taken'] = $unpaid_allocation['leave_taken'] + $prorate['unpaid_applied'];

						break;
						
					// Leave date is in the same year, start date is before 31st march and end date is after 31st march
					case 2:
						$max_bf_applied 	   = $this->countDays($date_from, $end_of_march);
						$bring_forward_applied = ($annual_allocation['bring_forward'] > 0 && $annual_allocation['bring_forward'] >= $max_bf_applied) ? $max_bf_applied : floatval($annual_allocation['bring_forward']);
						$leave_applied 	   	   = $application['days_applied'] - $bring_forward_applied;

						// DATA: Emergency Leave
						$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) + $application['days_applied'];

						// DATA: Annual Leave
						$data[$annual_allocation['id']]['bring_forward'] = floatval($annual_allocation['bring_forward']) - $bring_forward_applied;
						$data[$annual_allocation['id']]['leave_balance'] = floatval($annual_allocation['leave_balance']) - $leave_applied;
						// $data[$annual_allocation['id']]['leave_taken'] 	 = floatval($annual_allocation['leave_taken']) + $application['days_applied'];
						
						// DATA: Unpaid Leave
						// if($prorate['status'] == false) $data[$unpaid_allocation['id']]['leave_taken'] = $unpaid_allocation['leave_taken'] + $prorate['unpaid_applied'];

						break;

					// Leave date is in the same year, start date and end date after 31st march
					case 3:
						// DATA: Emergency Leave
						$leave_applied = (float) $application['days_applied'];
						$bring_forward_applied = 0;
						$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) + $application['days_applied'];

						// Check if days applied > allowed prorate leave
						$data[$annual_allocation['id']]['leave_taken'] 	 = ($prorate['status'] == false) ? floatval($annual_allocation['leave_taken']) + $prorate['prorate']['allowed_leave'] : floatval($annual_allocation['leave_taken']) + $application['days_applied'];
						$data[$annual_allocation['id']]['leave_balance'] = ($prorate['status'] == false) ? floatval($annual_allocation['leave_balance']) - $prorate['prorate']['allowed_leave'] : floatval($annual_allocation['leave_balance']) - $application['days_applied'];
						
						$transactions[$annual_allocation['id']]['leave_applied'] = $leave_applied;

						// if ($prorate['status'] == false) $data[$unpaid_allocation['id']]['leave_taken'] = $unpaid_allocation['leave_taken'] + $prorate['unpaid_applied'];

						break;

					// Leave date is across years
					case 4:
						$allocation_to = $this->model_leave->getAllocation(array(
							'a.user_id' => $application['user_id'], 
							'a.year' 		=> $date_to->format('Y'), 
							'a.type_id' => $application['type_id']
						));

						$annual_allocation_to = $this->model_leave->getAllocation(array(
							'a.user_id' => $application['user_id'], 
							'a.year' 		=> $date_to->format('Y'), 
							'a.type_id' => 1
						));

						break;
				}

				$transactions[$allocation['id']]['leave_applied'] 				 = $application['days_applied'];
				$transactions[$annual_allocation['id']]['leave_applied'] 		 = $leave_applied;
				$transactions[$annual_allocation['id']]['bring_forward_applied'] = $bring_forward_applied;

			} else if ($application['type_id'] == 4) {
				$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) + $application['days_applied'];

				$transactions[$allocation['id']]['leave_applied'] = $application['days_applied'];
			} else {
				$data[$allocation['id']]['leave_taken']   = floatval($allocation['leave_taken']) + $application['days_applied'];
				$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) - $application['days_applied'];

				$transactions[$allocation['id']]['leave_applied'] = $application['days_applied'];
			}

			// die(debug($transactions));

			// UPDATE ALLOCATIONS
			foreach ($data as $k => $v) {
				$this->model_general->update('hr__leave_allocation', $v, array('id'=>$k));
				
				// CREATE TRANSACTIONS
				$transactions[$k]['allocation_id'] 	= $k;
				$transactions[$k]['application_id'] = $application['id'];
				$transactions[$k]['function'] 		= 'approve';
				$transactions[$k]['created_by'] 	= $this->logged_user['id'];

				$this->model_general->insert('hr__leave_transaction', $transactions[$k]);
			}

			// UPDATE APPLICATION
			$update_application = $this->model_general->update('hr__leave_application', array('status' => 2, 'remarks' => $remarks, 'updated_by' => $this->logged_user['id'], 'updated_ts' => date('Y-m-d H:i:s'), 'approved_by' => $this->logged_user['id'], 'approved_ts' => date('Y-m-d H:i:s')), array('id'=>$id));

			if ($update_application) {
				$leave_name = $this->model_leave->getLeaveType($application['type_id'])['name'];
				$emails 	= $this->model_user->getUserEmail($application['user_id']);

				$email_data = array(
					'email'   => ($emails['primary_email']) ? $emails['primary_email'] : (($emails['secondary_email']) ? $emails['secondary_email'] : $emails['email']),
					'subject' => 'Leave Application Approved',
					'message' => 'Your '.$leave_name.' application from '.date('d/m/Y',strtotime($application['date_from'])).' to '.date('d/m/Y',strtotime($application['date_to'])).' was approved.'
				);

				$this->template->sendMail($email_data, 'leave');

				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application is approved."
				));
			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to approve this Leave Application. Please contact Administrator for further enquiries."
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function cancelApplication() {
		if(strtolower($this->logged_module['role']) == 'user') return false; 

		$id = $this->input->post('id');
		$remarks = ($this->input->post('remarks')) ? $this->input->post('remarks') : '';

		if ($id) {
			$application  = $this->model_leave->getApplication(array('a.id' => $id))[0];
			$transactions = $this->model_leave->getApplicationTransactions(array('application_id' => $application['id'], 'function' => 'approve'));

			if ($transactions) {
				foreach ($transactions as $trans) {
					if ($trans['allocation_id']) {
						$allocation = $this->model_leave->getAllocation(array('a.id' => $trans['allocation_id']));
						
						if ($application['type_id'] == 2) {
							if ($allocation['type_id'] == 1) {
								$data['bring_forward'] = (float) $allocation['bring_forward'] + $trans['bring_forward_applied'];
								$data['leave_balance'] = (float) $allocation['leave_balance'] + $trans['leave_applied'];

							} else {
								$data['leave_taken'] = (float) $allocation['leave_taken'] - $application['days_applied'];
							}
						} else {
							$data = array(
								'leave_taken' 	=> (float) $allocation['leave_taken'] - $application['days_applied'],
								'leave_balance' => (float) $allocation['leave_balance'] + $trans['leave_applied'],
								'bring_forward' => (float) $allocation['bring_forward'] + $trans['bring_forward_applied'],
							);
						}
	
						$this->model_general->update('hr__leave_allocation', $data, array('id' => $trans['allocation_id']));

						$this->model_general->insert('hr__leave_transaction', array(
							'allocation_id' 		=> $trans['allocation_id'],
							'application_id' 		=> $trans['application_id'],
							'leave_applied' 		=> $trans['leave_applied'],
							'bring_forward_applied' => $trans['bring_forward_applied'],
							'function' 				=> 'cancel',
							'created_by' 			=> $this->logged_user['id']
						));
					}
				}

				$update_application = $this->model_general->update('hr__leave_application', array('status' => 4, 'remarks' => $remarks, 'updated_by' => $this->logged_user['id'], 'updated_ts' => date('Y-m-d H:i:s')), array('id'=>$id));

				if ($update_application) {
					$leave_name = $this->model_leave->getLeaveType($application['type_id'])['name'];
					$emails 	= $this->model_user->getUserEmail($application['user_id']);

					$email_data = array(
						'email'   => ($emails['primary_email']) ? $emails['primary_email'] : (($emails['secondary_email']) ? $emails['secondary_email'] : $emails['email']),
						'subject' => 'Leave Application Cancelled',
						'message' => 'Please be informed that your '.$leave_name.' application from '.date('d/m/Y',strtotime($application['date_from'])).' to '.date('d/m/Y',strtotime($application['date_to'])).' was cancelled.'
					);

					$this->template->sendMail($email_data, 'leave');

					print json_encode(array(
						"status" => "Success",
						"msg"	 => "Leave Application is cancelled."
					));
				}
			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to cancel this Leave Application. Please contact Administrator for further enquiries."
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function rejectApplication() {
		$data = $this->input->post();

		if(isset($data['id'])) {
			$id = $data['id'];
			unset($data['id']);

			$application  = $this->model_leave->getApplication(array('a.id' => $id))[0];
			$remarks 	  = ($this->input->post('remarks')) ? $this->input->post('remarks') : '';

			$data['status']		= 3;
			$data['remarks']	= $remarks;
			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_application', $data, array('id'=>$id));

			if($ok) {
				$leave_name = $this->model_leave->getLeaveType($application['type_id'])['name'];
				$emails 	= $this->model_user->getUserEmail($application['user_id']);

				$email_data = array(
					'email'   => ($emails['primary_email']) ? $emails['primary_email'] : (($emails['secondary_email']) ? $emails['secondary_email'] : $emails['email']),
					'subject' => 'Leave Application Rejected',
					'message' => 'With regret your '.$leave_name.' application from '.date('d/m/Y',strtotime($application['date_from'])).' to '.date('d/m/Y',strtotime($application['date_to'])).' was rejected.'
				);

				$this->template->sendMail($email_data, 'leave');

				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application rejected successfully."
				));

			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to reject Leave Application."
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function createRequest() {
		$data = $this->input->post();

		if ($data) {
			$data['created_by'] = $this->logged_user['id'];

			$id = $this->model_general->insert('hr__leave_allocation_request', $data);

			if($id)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation Request created successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave Allocation Request."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function updateRequest() {
		$data = $this->input->post();

		if(isset($data['id'])) {
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_allocation_request', $data, array('id'=>$id));

			if($ok) {
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation Request updated successfully."
				));
			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Allocation Request."
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function deleteRequest() {
		$data = $this->input->post();
		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_allocation_request', $data, array('id'=>$data['id']));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation Request deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Allocation Request."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

/*	// function cancelApplication() {
	// 	if(strtolower($this->logged_module['role']) == 'user') return false; 

	// 	$id = $this->input->post('id');

	// 	if ($id) {
	// 		$application   = $this->model_leave->getApplication(array('a.id' => $id))[0];
	// 		$date_from 	   = new DateTime(date($application['date_from']));
	// 		$date_to	   = new DateTime(date($application['date_to']));
	// 		$end_of_march  = new DateTime(date($date_from->format('Y').'-03-31'));
	// 		$start_of_year = new DateTime(date($date_from->format('Y').'-01-01'));
	// 		$end_of_year   = new DateTime(date($date_from->format('Y').'-12-31'));
			
	// 		$allocation = $this->model_leave->getAllocation(array(
	// 			'a.user_id' => $application['user_id'], 
	// 			'a.year' 	=> $date_from->format('Y'), 
	// 			'a.type_id' => $application['type_id']
	// 		));

	// 		$date_rule = $this->checkLeaveDateRules($date_from, $date_to);

	// 		/**
	// 		 * Annual Leave Allocation Date Rules:
	// 		 * 
	// 		 * 1 : Leave date is in the same year, start date and end date before 31st march
	// 		 * 2 : Leave date is in the same year, start_date is before 31st march and end date is after 31st march
	// 		 * 3 : Leave date is in the same year, start date and end date after 31st march
	// 		 * 4 : Leave date is across years
	// 		 * 
	// 		 */
/*
	// 		$application_transactions = $this->model_leave->getApplicationTransactions(array('application_id' => $application['id']));

	// 		if ($application['type_id'] == 1) {
	// 			switch ($date_rule) {
	// 				case 1:
	// 					// check if leave uses bring forward
	// 					$total_applied = floatval($application['days_applied']);
	// 					$bring_forward_applied = 0;
	// 					$annual_applied = $total_applied - $bring_forward_applied;

	// 					$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) - floatval($total_applied);
	// 					$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) + floatval($annual_applied);

	// 					if ($bring_forward_applied > 0) $data[$allocation['id']]['bring_forward'] = floatval($allocation['bring_forward']) + floatval($bring_forward_applied);

	// 					break;
	// 				case 2:
	// 					$bring_forward_applied;

	// 					$data[$allocation['id']]['leave_taken']   = 0;
	// 					$data[$allocation['id']]['leave_balance'] = 0;
	// 					break;
	// 				case 3:
	// 					$data[$allocation['id']]['leave_taken']	  = floatval($allocation['leave_taken']) - floatval($application['days_applied']);
	// 					$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) + floatval($application['days_applied']);
	// 					break;
	// 				case 4:
	// 					$allocation_to = $this->model_leave->getAllocation(array(
	// 						'a.user_id' => $application['user_id'],
	// 						'a.year' 	=> $date_to->format('Y'), 
	// 						'a.type_id' => $application['type_id']
	// 					));

	// 					$data[$allocation['id']]['leave_taken']   = 0;
	// 					$data[$allocation['id']]['leave_balance'] = 0;

	// 					$data[$allocation_to['id']]['leave_taken']   = 0;
	// 					$data[$allocation_to['id']]['leave_balance'] = 0;

	// 					break;
	// 				default:
	// 					break;
	// 			}
	// 		} else if ($application['type_id'] == 2) {
	// 			$annual_allocation = $this->model_leave->getAllocation(array(
	// 				'a.user_id' => $application['user_id'], 
	// 				'a.year' 	=> $date_from->format('Y'), 
	// 				'a.type_id' => 1
	// 			));

	// 			switch ($date_rule) {
	// 				case 1:
	// 					// check if leave uses bring forward
	// 					$total_applied = floatval($application['days_applied']);
	// 					$bring_forward_applied = 0;
	// 					$annual_applied = $total_applied - $bring_forward_applied;

	// 					$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) - floatval($total_applied);
	// 					$data[$annual_allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) + floatval($annual_applied);

	// 					if ($bring_forward_applied > 0) $data[$annual_allocation['id']]['bring_forward'] = floatval($allocation['bring_forward']) + floatval($bring_forward_applied);

	// 					break;
	// 				case 2:
	// 					$bring_forward_applied;
						
	// 					$data[$allocation['id']]['leave_taken'] = 0;
	// 					$data[$annual_allocation['id']]['leave_balance'] = 0;
	// 					break;
	// 				case 3:
	// 					$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) - floatval($application['days_applied']);
	// 					$data[$annual_allocation['id']]['leave_balance'] = floatval($annual_allocation['leave_balance']) + floatval($application['days_applied']);
	// 					break;
	// 				case 4:
	// 					$allocation_to = $this->model_leave->getAllocation(array(
	// 						'a.user_id' => $application['user_id'],
	// 						'a.year' 	=> $date_to->format('Y'), 
	// 						'a.type_id' => $application['type_id']
	// 					));

	// 					$annual_allocation_to = $this->model_leave->getAllocation(array(
	// 						'a.user_id' => $application['user_id'],
	// 						'a.year' 	=> $date_to->format('Y'), 
	// 						'a.type_id' => $application['type_id']
	// 					));

	// 					// check if using bring forward
	// 					$data[$allocation['id']]['leave_taken'] = 0;
	// 					$data[$annual_allocation['id']]['leave_balance'] = 0;

	// 					$data[$allocation_to['id']]['leave_taken'] = 0;
	// 					$data[$annual_allocation_to['id']]['leave_balance'] = 0;
	// 					break;
	// 				default:
	// 					break;
	// 			}
	// 		} else if ($application['type_id'] == 4) {
	// 			$data[$allocation['id']]['leave_taken'] = floatval($allocation['leave_taken']) - floatval($application['days_applied']);
	// 		} else {
	// 			$data[$allocation['id']]['leave_balance'] = floatval($allocation['leave_balance']) + floatval($application['days_applied']);
	// 			$data[$allocation['id']]['leave_taken']	 = floatval($allocation['leave_taken']) - floatval($application['days_applied']);
	// 		}

	// 		die(debug($data));

	// 		$transactions[$allocation['id']]['leave_applied'] 		  = (float) ( $leave_applied ) ? $leave_applied : 0;
	// 		$transactions[$allocation['id']]['bring_forward_applied'] = (float) ( $bring_forward_applied ) ? $bring_forward_applied : 0;

	// 		// UPDATE ALLOCATIONS
	// 		foreach ($data as $k => $v) {
	// 			$this->model_general->update('hr__leave_allocation', $v, array('id'=>$k));
	// 		}

	// 		// UPDATE APPLICATION
	// 		$update_application = $this->model_general->update('hr__leave_application', array('status' => 4, 'updated_by' => $this->logged_user['id'], 'updated_ts' => date('Y-m-d H:i:s')), array('id'=>$id));

	// 		if ($update_application) {
	// 			print json_encode(array(
	// 				"status" => "Success",
	// 				"msg"	 => "Leave Application is cancelled."
	// 			));
	// 		} else {
	// 			print json_encode(array(
	// 				"status" => "Error",
	// 				"msg"	 => "System failed to cancel this Leave Application. Please contact Administrator for further enquiries."
	// 			));
	// 		}
	// 	} else {
	// 		print json_encode(array(
	// 			"status" => "Error",
	// 			"msg"	 => "Data is missing."
	// 		));
	// 	}
	// }  */

	function checkLeaveDateRules($date_from, $date_to) {
		// if leave in the same year
		if ($date_from->format('Y') == $date_to->format('Y')) {
			// if leave date before 31/3 (last use of bring forward)
			if($date_from->format('n') < 4 && $date_to->format('n') < 4) {
				return 1;

			// if leave date from before and after 31/3
			} else if($date_from->format('n') < 4 && $date_to->format('n') >= 4) {
				return 2;

			// if leave date after 31/3
			} else {
				return 3;
			}

		// if leave is across years
		} else {
			return 4;
		}
	}


	function checkIfApplicationUsesBringForward($application_id) {
		$application = $this->model_leave->getApplication(array('a.id' => $application_id));

		$date_from = new DateTime($application['date_from']);
		$date_to   = new DateTime($application['date_to']);
		
		$allocation = $this->model_leave->getAllocation(array('a.user_id' => $application['user_id'], 'a.year' => $date_from->format('Y'), 'a.type_id' => 1));
		if ($application['id'] == 2) $emergency_allocation = $this->model_leave->getAllocation(array('a.user_id' => $application['user_id'], 'a.year' => $date_from->format('Y'), 'a.type_id' => 1));
	}

	function uploadAttachment()
	{
		$data = $this->input->post();

		if(isset($data['attachment_id'])) {

		} else {

		}
	}

	function deleteAttachment()
	{
		$data = $this->input->post();

		if(isset($data['attachment_id'])) {

		} else {
			
		}
	}

	function countDaysByType($leave_type_id, $branch_id=null) {
		$start 	   = new DateTime(date('2019-01-02'));
		$end	   = new DateTime(date('2019-01-05')); 

		$type = $this->model_leave->getLeaveType($leave_type_id);

		if ($branch_id) $branch   = $this->model_company->getBranches(1, $branch_id);
		if ($branch_id) $holidays = $this->model_holiday->getHolidayByBranch(1, $branch_id);
		// die(debug($holidays));

		$end->modify('+1 day');

		$interval = $end->diff($start);

		// total days
		$days = $interval->days;

		// create an iterateable period of date (P1D equates to 1 day)
		$period = new DatePeriod($start, new DateInterval('P1D'), $end);

		// best stored as array, so you can add more than one
		// $holidays = $this->model_leave->getHolidays($year);
		if($type['include_holiday'] == false) {
			foreach($period as $dt) {
				$curr = $dt->format('D');

				// substract if Saturday or Sunday
				if ($curr == 'Sat' || $curr == 'Sun') {
					$days--;
				}

				// (optional) for the updated question
				elseif (in_array($dt->format('Y-m-d'), $holidays)) {
					$days--;
				}
			}
		}

		return $days; // 4
	}

	function countDays($start, $end)
	{
		$end->modify('+1 day');

		$interval = $end->diff($start);

		// total days
		$days = $interval->days;

		// create an iterateable period of date (P1D equates to 1 day)
		$period = new DatePeriod($start, new DateInterval('P1D'), $end);

		// best stored as array, so you can add more than one
		// $holidays = $this->model_leave->getHolidays($year);

		foreach($period as $dt) {
			$curr = $dt->format('D');

			// substract if Saturday or Sunday
			if ($curr == 'Sat' || $curr == 'Sun') {
				$days--;
			}

			// (optional) for the updated question
			// elseif (in_array($dt->format('Y-m-d'), $holidays)) {
			// 	$days--;
			// }
		}

		return $days; // 4
	}

	function countDaysIncludeWeekend($start, $end)
	{
		$end->modify('+1 day');

		$interval = $end->diff($start);

		// total days
		$days = $interval->days;

		// create an iterateable period of date (P1D equates to 1 day)
		$period = new DatePeriod($start, new DateInterval('P1D'), $end);

		// best stored as array, so you can add more than one
		// $holidays = $this->model_leave->getHolidays($year);

		foreach($period as $dt) {
			$curr = $dt->format('D');

			// // substract if Saturday or Sunday
			// if ($curr == 'Sat' || $curr == 'Sun') {
			// 	$days--;
			// }

			// (optional) for the updated question
			// elseif (in_array($dt->format('Y-m-d'), $holidays)) {
			// 	$days--;
			// }
		}

		return $days; // 4
	}

	// Number of days - holidays - weekends
	function countWorkingDays($start, $end, $branch_id=null) {
		$end->modify('+1 day');

		$interval = $end->diff($start);

		// total days
		$days = $interval->days;

		// create an iterateable period of date (P1D equates to 1 day)
		$period = new DatePeriod($start, new DateInterval('P1D'), $end);

		// best stored as array, so you can add more than one
		// $holidays = $this->model_leave->getHolidays($year);

		if ($branch_id) $branch = $this->model_company->getBranch(1, $branch_id);
		if ($branch_id) $holidays = $this->model_holiday->getHolidaysByBranch(1, $branch_id);
		 

		foreach($period as $dt) {
			$curr = $dt->format('D');

			// substract if Saturday or Sunday
			if ($curr == 'Sat' || $curr == 'Sun') {
				$days--;
			}

			// (optional) for the updated question
			// elseif (in_array($dt->format('Y-m-d'), $holidays)) {
			// 	$days--;
			// }
		}


		return $days; // 4
	}

	function updatedCountDays($start, $end, $leave_type_id=null, $branch_id=null) {
		if ($leave_type_id) {
			switch ($leave_type_id) {
				case 1:
					# code...
					break;
				
				default:
					# code...
					break;
			}
		}

		if ($branch_id) {
			
		}
		// count number of days between two dates
		// certain leave types affect if include public holidays and weekends
		// public holiday days varies between branches (locations)
		
	}

	function summary($year=0,$userID=0) {
		$mode=false;
		$year = ($year>0)?$year:date('Y');
		$last_year = $year - 1; 
		$this->db->select('concat(staff,"[",user_id,"]</br>",ifnull(date_joined,"")) as staff')
				->select('leave_type,last_year_entitled, last_year_brought_forward, last_year_taken_b4_april, last_year_taken_after_april, last_year_balance')
				->select('if(last_year_balance > (last_year_entitled * 0.5),(last_year_balance - (last_year_entitled * 0.5)),NULL) as leave_to_cash')
				->select('last_year_brought_forward,bring_forward_entitled, leave_entitled,leave_applied_before_april,leave_applied_after_april, current_balance')
				->where('year',$year)
				->order_by('staff,leave_type ASC');
		if($userID > 0) $this->db->where('user_id',$userID);		
				
		$rs = $this->db->get('view_leave_summary')
				->result_array(); 		
//		$rs = $this->db->query('select concat(c.name,"[",a.user_id,"]<br>",ued.date_joined) as name, t.name as leave_type,  aa.leave_entitled as last_year_entitled, aa.leave_balance as last_year_balance, if(aa.leave_balance > (0.5 * aa.leave_entitled),aa.leave_balance - (0.5 * aa.leave_entitled),0) as leave_payable, a.bring_forward_entitled, a.leave_entitled, sum(if(b.date_from >= "'.$year.'-01-01" and b.date_from < "'.$year.'-04-01" ,b.days_applied,0)) as leave_applied_before_april, sum(if(b.date_from >= "'.$year.'-04-01",b.days_applied,0)) as leave_applied_after_april, a.leave_balance from (hr__leave_allocation a left outer join hr__leave_allocation aa on a.user_id = aa.user_id and a.type_id = aa.type_id and aa.year = '.$last_year .'), hr__leave_application b, hr__leave_type t, user c, user__employment_detail ued where c.id = a.user_id and a.user_id = b.user_id and a.type_id = b.type_id and a.year = '.$year.' and a.type_id in (1,2) and b.is_delete = 0 and t.id = a.type_id and b.status < 3 and a.user_id = ued.user_id group by a.user_id , a.type_id, a.year order by c.name, t.name ')->result_array();
//		echo $this->db->last_query(); 
		$last_year_entitled = $year-1;
		
		$date = date("d-m-Y");
		$previousYear = $year - 2;
		$body = array(
				'table' => array(
					'header' => array(
						'Staff Name/Date joined',
						'Leave Type','['.$last_year_entitled.']<br/> Entitled','['.$last_year_entitled.']<br/> Brought Forward From '.$previousYear,'['.$last_year_entitled.']<br/> Taken Before April','['.$last_year_entitled.']<br/> Taken After Mac','['.$last_year_entitled.']<br/> Leave Balance <br/><small style="font-size:0.5em">'.date('d-m-Y',strtotime('31-12-'.$last_year_entitled)).'</small>', '['.$last_year_entitled.']<br/> Leave To Cash ',
						'['.$year.']<br/> Bring forward Entitled','['.$year.'] Entitled', '['.$year.']<br/> Leave before  April', '['.$year.']<br/> Leave after Mac', '['.$year.']<br/> Current Balance <br/><small style="font-size:0.5em">'.date('d-m-Y').'</small>'
					),
					'right-column' => array(3,4,5,6,7,8,9,10,11,12,13),
					'total-column' => array(),
					'body' => $rs,
					'footer' => array(
					)
				),
				'filter' => array(
				)
			);
		$header = array();
		$header['apps'] = 'SPS';
		$header['module'] = 'e-Leave';
		$header['title'] = 'LEAVE SUMMARY FOR THE YEAR '.$year.' AS AT ' . $date;

		// excel data
		$headerData['rptTitle'] = 'ALL CUSTOMER LIST REPORT AS AT '. $date;
		$headerData['leftContent'] = array();

		$bodyData['rptDataDetail'] = $rs;
		$bodyData['tableHeader'] = array(
			'Company Name',
			'Company No.',
			'Email'
		);
		$bodyData['selectFields'] = array(
			'name',
			'roc_no',
			'email'
		);
		$bodyData['excelTitle'] = $header['title'];

		if(!$mode){
			//print
			$this->load->view('CRM/report/header.php', $header);
			$this->load->view('CRM/report/printList.php', $body);
			$this->load->view('CRM/report/footer.php');
		}else{
			//excel
			$this->load->helper('excel');
			excel($headerData, array($bodyData));
		}
	}

// akmal 20191128 check for entitlement before run allocation 
	private function checkEntitlement($year=0,$typeID=1){
		$year =($year ==0)?date("Y"):$year; 
		$rs = $this->model_leave->getEntitlement(array('a.year' => $year, 'a.type_id' => $typeID)); 
//		echo $this->db->last_query(); 
		return  (sizeof($rs)> 0)?true:false; 
	}

//akmal 20200106 to check leave balance by calculation 
	function checkLeaveBalanceByCalculation($year=0, $userID=0){
		if($year ==0) $year=date("Y");
		$sql = 'select a.*, d.date_joined, d.name from hr__leave_allocation a, user__employment_detail d where a.user_id = d.user_id and a.type_id = 1 and a.year='.$year.' order by a.user_id';
		if($userID >0)
			$sql .= ' and user_id='.$userID;

		$rsUser = $this->db->query($sql)->result_array();
		echo '<table border=1><tr><th>Date join</th><th>Name </th><th>User ID</th><th>Bring forward entt</th><th>Bring Forward</th><th>Entitled</th><th>b4april</th><th>afterapril</th><th>Balance</th><th>Calculation Balance</th></tr>';
		foreach($rsUser as $userRow){
//			var_dump($userRow);
			$leaveApplyBeforeApril = $this->db->query('select ifnull(sum(days_applied),0) as leaveB4April from hr__leave_application where year(date_from)='.$year.' and month(date_from) < 4 and user_id='.$userRow['user_id'].' and type_id in (1,2) and status = 2 and is_delete =0' )->result_array()[0]['leaveB4April'];
			$leaveApplyAfterApril = $this->db->query('select ifnull(sum(days_applied),0) as leaveAfterApril from hr__leave_application where year(date_from)='.$year.' and month(date_from) > 3 and user_id='.$userRow['user_id'].' and type_id in (1,2) and status = 2 and is_delete =0')->result_array()[0]['leaveAfterApril'];
//			$var = 13 - substr($userRow['date_joined'],5,2);
//			$entitled = $userRow['leave_entitled']/12 * $var;
//			echo $var.'-'.$entitled.'<br>';
//			$leaveBalance = round($entitled) - $leaveApplyBeforeApril - $leaveApplyAfterApril;
			$leaveBalance =  $userRow['leave_entitled'] - $leaveApplyAfterApril;
			if($userRow['user_id'] == 262 || $userRow['user_id'] == 248)
				echo '<tr><td colspan=8>'.$userRow['leave_entitled']/12 .' *'. substr($userRow['date_joined'],5,2).'</td></tr>';
//			if($userRow['bring_forward_entitled'] > 0 && $userRow['bring_forward_entitled'] <= $leaveApplyBeforeApril)
				if($leaveApplyBeforeApril >0) {
				$leaveBalance = $leaveBalance - ($leaveApplyBeforeApril- $userRow['bring_forward_entitled']);
			//if bring forward > leaveapplierbeforeapril, bring forward will be forfeited(burn) 
//			if($userRow['leave_balance'] <> $leaveBalance && substr($userRow['date_joined'],0,4) > '0000') {
				echo '<tr><td>'.$userRow['date_joined'].'</td><td>'.$userRow['name'].'</td><td>'.$userRow['user_id'].'</td><td>'.$userRow['bring_forward_entitled'].'</td><td>'.$userRow['bring_forward'].'</td><td>'.$userRow['leave_entitled'].'</td><td>'.$leaveApplyBeforeApril.'</td><td>'.$leaveApplyAfterApril.'</td><td>'.$userRow['leave_balance'].'</td><td>'.$leaveBalance.'</td></tr>';
				
//				$this->db->query('update hr__leave_allocation set leave_balance = '.$leaveBalance.' where  year = '.$userRow['year'].' and type_id = 1 and user_id ='.$userRow['user_id']);
			}
		}
		echo '</table>';
	}

	function AJAX_cancelApplication()	{
/* 	1.get leave type
	2.follow rule based on leave type
	3.update leave balance
	4. update leave status to cancel	
*/		
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$id = $data['id'];
			unset($data['id']);

//do cancelation here
			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Application."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_rejectApplication()	{
/* 	1.get leave type
	2.follow rule based on leave type
	3.update leave status to reject	
*/		
		$data = $this->input->post();
	}

	function AJAX_getUserDetail() {
		$data = $this->input->post();
		
		if($data['id']) {
			$user 			= $this->model_user->getUsers($data['id']);
			$exam 			= $this->model_exam->get_exam_list($data['id']);
			$study_leave 	= $this->model_leave->get_study_leave_by_user($data['id']);

			if($user) {
				print json_encode(array(
					"status" => "success",
					"user"	 => $user,
					"exam"	 => $exam,
					"study_leave" => $study_leave,
				));
			} else {
				print json_encode(array(
					"status" => "failed"
				));
			}
		}
	}

	function AJAX_getEntitlementSetup() {
		$data = $this->input->post();

		if ($data) {
			$entitlement = $this->model_leave->getEntitlement(array('a.year' => $data['year'], 'a.type_id' => $data['type_id'], 'a.category_id' => $data['category_id']));
			if($entitlement) {
				print json_encode(array(
					"status"     => "success",
					"entitlement" => $entitlement,
					"sql" => $this->db->last_query()
				));
			} else {
				print json_encode(array(
					"status" 	=> "failed"
				));
			}
		}
	}
		
	function AJAX_getEntitlement() 	{
		$entitlement_id = $this->input->get('id');

		$entitlement = $this->model_leave->getEntitlement(array('a.id' => $entitlement_id));

		if($entitlement) {
			print json_encode(array(
				"status"     => "success",
				"entitlement" => $entitlement
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed"
			));
		}
	}

	function AJAX_getEntitlementByYear() {
		$year 	 = $this->input->get('year');
		$type_id = $this->input->get('type_id');

		$entitlements = $this->model_leave->getEntitlement(array('a.year' => $year, 'a.type_id' => $type_id));

		if($entitlements) {
			print json_encode(array(
				"status"     => "success",
				"entitlements" => $entitlements
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed"
			));
		}
	}

	function AJAX_getEntitlementByFilter() {
		$data = $this->input->get();

		$filters = array();

		if (isset($data['year'])) 		 $filters['a.year'] 	   = $data['year'];
		if (isset($data['type_id'])) 	 $filters['a.type_id'] 	   = $data['type_id'];
		if (isset($data['category_id'])) $filters['a.category_id'] = $data['category_id'];

		if ($data) {
			$entitlement = $this->model_leave->getEntitlement($filters);

			if($entitlement) {
				print json_encode(array(
					"status"     => "success",
					"entitlements" => $entitlement
				));
			} else {
				print json_encode(array(
					"status" 	=> "failed"
				));
			}
		}
	}
	function AJAX_getApplication()	{
		$application_id = $this->input->post('id');
		$application = $this->model_leave->getApplication(array("a.id" => $application_id));
		if($application) {
			print json_encode(array(
				"status"     => "success",
				"application" => $application
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed"
			));
		}
		/* 
			FILTERS
			- multiple/single by id
			- by staff
			- by department
			- by manager approval
			- by leave type
			
			SORTING
			- by application date
			- by approval/cancel/reject date
			- by user
		*/
	}

	function AJAX_getLeaveBetweenDate() 	{
		$user_id   = $this->input->post('user_id');
		$date_from = date('Y-m-d', strtotime($this->input->post('date_from')));
		$date_to   = date('Y-m-d', strtotime($this->input->post('date_to')));

		$leaveDate = $this->model_leave->getLeaveBetweenDate($user_id, $date_from, $date_to);
		$query 	   = $this->db->last_query();

		if($leaveDate) {
			print json_encode(array(
				"status"     => "success",
				"leave_date" => $leaveDate,
				"query"		 => $query,
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed",
				"query"		=> $query,
			));
		}
	}

	function AJAX_getLeaveTaken() 	{
		$user_id   = $this->input->post('user_id');
		$date_from = date('Y-m-d', strtotime($this->input->post('date_from')));
		$date_to   = date('Y-m-d', strtotime($this->input->post('date_to')));

		$leave_dates = $this->model_leave->getLeaveTaken($user_id, $date_from, $date_to);

		if($leave_dates) {
			print json_encode(array(
				"status"     => "success",
				"leave_date" => $leave_dates
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed"
			));
		}
	}

	function getLeaveUntilMonth() 	{
		$user_id 	 = $this->input->post('user_id');
		$date_to = date('Y-m-d', strtotime($this->input->post('date_to')));

		$leave_dates = $this->model_leave->getLeaveUntilMonth($user_id, $date_to);

		if($leave_dates) {
			print json_encode(array(
				"status"     => "success",
				"leave_date" => $leave_dates
			));
		} else {
			print json_encode(array(
				"status" 	=> "failed"
			));
		}
	}

	function AJAX_getAllocation() {
		$data = $this->input->post();
		if ($data) {
			$allocation = $this->model_leave->getAllocation(array('a.id' => $data['id'])); 

			if ($allocation) {
				print json_encode(array(
					"status" 	 => "Success",
					"allocation" => $allocation,
					"sql" => $this->db->last_query(),
				));
			} else {
				print json_encode(array(
					"status" 	 => "Failed"
				));
			}
		}
	}
	function AJAX_getAllocation_currentYear() {
		$data = $this->input->post();
		// die(debug($data));
		$filter = array();
		foreach($data as $key => $val) $filter['a.'.$key] = $val; 
		if (!empty($filter)) {
			$allocation = $this->model_leave->getAllocation_currentYear($filter);

			if ($allocation) {
				print json_encode(array(
					"status" 	 => "Success",
					"allocation" => $allocation, //$allocation[0],
					"sql" 		=> $this->db->last_query(),  
				));
			} else {
				print json_encode(array(
					"status" 	=> "Failed",
					"sql" 		=> $this->db->last_query(), 
				));
			}
		}
	}
	function AJAX_getAllocationHistory() {
		$data = $this->input->post();
		$filter = array('user_id' => $data['user_id']);
		if(isset($data['type_id'])) $filter['type_id'] = $data['type_id'];
		$rsAllocation = $this->model_leave->getAllocationHistory($filter);
		if (!empty($rsAllocation)) {
			print json_encode(array(
				"status" 			=> "Success",
				"rsAllocationHistory" => $rsAllocation,
				"sql" => $this->db->last_query()
			));
		} else { 
			print json_encode(array(
				"status" 			=> "Failed",
				"sql" => $this->db->last_query()
			));
		} 
	}

	function AJAX_getLeaveBalance(){
		$data = $this->input->post(); //userid, datafrom
		$data['year'] = (isset($data['datafrom']))? date('Y',$data['datafrom']) : date('Y');
		
		$rs = $this->model_leave->getLeaveBalance($data);
		
		if($rs)	print json_encode(array('status' => 'success', 'result' => $rs));
		else 	print json_encode(array('status' => 'failed'));
	}
	
	function AJAX_checkBalance() {
		$data = $this->input->post(); //user_id ,date_from,date_to,type_id, daysApply
		$data['type_id'] = ($data['type_id'] == 2) ? 1: $data['type_id']; //check if emergency, use al leave. 
		$balance = $this->model_leave->getLeaveBalance(array('year'=>$data['year'],'user_id'=>$data['user_id'],'type_id'=>$data['type_id']));
		
		print json_encode($balance);
	}
	function AJAX_getProRate() {
		$data = $this->input->post();
		if ($data) {
			$prorate = $this->getProRate($data['user_id'], $data['date_from']);

			if ($data['date_from'] && $data['date_to']) {
				$date_from = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
				$date_to	 = new DateTime(date('Y-m-d', strtotime($data['date_to'])));

				$next_date_from = new DateTime(date('Y-m-d', strtotime('+1 day', strtotime($data['date_from']))));
				$prev_date_to = new DateTime(date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))));

				$half_day = 0.5;
				
				// COUNT DAYS APPLIED
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDays($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDays($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}

			if ($prorate) {
				$respond = array('status'  => 'success', 'prorate' => $prorate);

				if ($data['days_applied']) $respond['days_applied'] = $data['days_applied'];

				print json_encode($respond);
			} else {
				print json_encode(array('status' => 'failed'));
			}
		} else {
			print json_encode(array('status' => 'failed'));
		}
	}

	function AJAX_getLeaveSummary()	{
		$data = $this->input->post();

		if ($data['id']) {
			$filters = (isset($data['year'])) ? array('a.user_id' => $data['id'], 'a.year' => $data['year']) : array('a.user_id' => $data['id']);
			
			$allocations  = $this->model_leave->getAllocation($filters);
			$applications = $this->model_leave->getApplication($filters);

			if ($allocations) {
				print json_encode(array(
					"status" 			 => "Success",
					"allocations"  => $allocations,
					"applications" => $applications
				));
			};
		}
	}

	function AJAX_createType()	{
		$data = $this->input->post();

		if($data)
		{
			$data['created_by'] = $this->logged_user['id'];

			$id = $this->model_general->insert('hr__leave_type', $data);

			if($id)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Type created successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave Type."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_updateType()	{
		$data = $this->input->post();
		if(isset($data['id']))
		{
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_type', $data, array('id'=>$id));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Type updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Type."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_deleteType()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_type', $data, array('id'=>$data['id']));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Type deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Type."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_saveEntitlement()	{
		$entitlements = $this->input->post('entitlements');
//var_dump($entitlements);
		if($entitlements) {
			foreach($entitlements as $entitlement) { 
				$entitlement['created_by'] = $this->logged_user['id'];

				//$ok = $this->db->insert_batch('hr__leave_entitlement', $entitlement);
				$ok = $this->db->insert('hr__leave_entitlement', $entitlement);
			}
// echo $this->db->last_query();
// exit();
			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Entitlement created successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave entitlement."
				));
			}
		}
	}

	function AJAX_createEntitlement()	{
		$data = $this->input->post();

		if($data)
		{
			$data['created_by'] = $this->logged_user['id'];

			$id = $this->model_general->insert('hr__leave_entitlement', $data);

			if($id)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Entitlement created successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave entitlement."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_updateEntitlement()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_entitlement', $data, array('id'=>$id));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Entitlement updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Entitlement."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_deleteEntitlement()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_entitlement', $data, array('id'=>$data['id']));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Entitlement deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Entitlement."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_createAllocation()	{
		$data = $this->input->post();

		if($data)
		{
			if($data['type_id'] == 1) {
				$batch = array(
					array(
						'user_id' => $data['user_id'],
						'entitlement_id' => $data['entitlement_id'],
						'year' => $data['year'],
						'type_id' => $data['type_id'],
						'balance_entitled' => $data['balance_entitled'],
						'leave_balance' => $data['leave_balance'],
						'bring_forward_entitled' => $data['bring_forward_entitled'],
						'bring_forward' => $data['bring_forward'],
						'leave_entitled' => $data['leave_entitled'],
						'created_by' => $this->logged_user['id']
					),
					array(
						'user_id' => $data['user_id'],
						'entitlement_id' => 0,
						'year' => $data['year'],
						'type_id' => 2,
						'balance_entitled' => 0,
						'leave_balance' => 0,
						'bring_forward_entitled' => 0,
						'bring_forward' => 0,
						'leave_entitled' => 0,
						'created_by' => $this->logged_user['id']
					),
					array(
						'user_id' => $data['user_id'],
						'entitlement_id' => 0,
						'year' => $data['year'],
						'type_id' => 4,
						'balance_entitled' => 0,
						'leave_balance' => 0,
						'bring_forward_entitled' => 0,
						'bring_forward' => 0,
						'leave_entitled' => 0,
						'created_by' => $this->logged_user['id']
					)
				);

				$ok = $this->db->insert_batch('hr__leave_allocation', $batch);

			} else {
				$data['created_by'] = $this->logged_user['id'];
				$ok = $this->model_general->insert('hr__leave_allocation', $data);
			}

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation created successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave Allocation."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_createAllocationBulk() {
		$data = $this->input->post();

		var_dump($data);

		if ($data['save_data']) {
			$data = $data['save_data'];

			$allocations = array();

			foreach($data as $user) {
				if ($al_data = $user['new_allocation']['al_data']) {
					$al_allocation = array(
						'user_id' 				 => $user['user_id'],
						'entitlement_id' 		 => $al_data['entitlement_id'],
						'year' 					 => $user['year'],
						'type_id' 				 => 1,
						'balance_entitled' 		 => $al_data['allocate_leave'],
						'leave_balance' 		 => $al_data['allocate_leave'],
						'bring_forward_entitled' => $al_data['bring_forward'],
						'bring_forward' 		 => $al_data['bring_forward'],
						'leave_entitled' 		 => $al_data['allocate_leave'],
						'created_by' 			 => $this->logged_user['id']
					);

					$el_allocation = array(
						'user_id' 	 			 => $user['user_id'],
						'entitlement_id' 		 => 0,
						'year' 		 			 => $user['year'],
						'type_id' 	 			 => 2,
						'balance_entitled' 		 => 0,
						'leave_balance' 		 => 0,
						'bring_forward_entitled' => 0,
						'bring_forward' 		 => 0,
						'leave_entitled' 		 => 0,
						'created_by' => $this->logged_user['id']
					);

					$un_allocation = array(
						'user_id' 	 			 => $user['user_id'],
						'entitlement_id' 		 => 0,
						'year' 		 			 => $user['year'],
						'type_id' 	 			 => 4,
						'balance_entitled' 		 => 0,
						'leave_balance' 		 => 0,
						'bring_forward_entitled' => 0,
						'bring_forward' 		 => 0,
						'leave_entitled' 		 => 0,
						'created_by' => $this->logged_user['id']
					);

					array_push($allocations, $al_allocation);
					array_push($allocations, $el_allocation);
					array_push($allocations, $un_allocation);
				}

				if ($mc_data = $user['new_allocation']['mc_data']) {
					$mc_allocation = array(
						'user_id' 		   		 => $user['user_id'],
						'entitlement_id'   		 => $mc_data['entitlement_id'],
						'year' 			   		 => $user['year'],
						'type_id' 		   		 => 3,
						'balance_entitled' 		 => $mc_data['allocate_leave'],
						'leave_balance'    		 => $mc_data['allocate_leave'],
						'bring_forward_entitled' => 0,
						'bring_forward' 		 => 0,
						'leave_entitled'   		 => $mc_data['allocate_leave'],
						'created_by' 	   		 => $this->logged_user['id']
					);

					array_push($allocations, $mc_allocation);
				}
			}

			$ok = $this->db->insert_batch('hr__leave_allocation', $allocations);
			
			if($ok) {
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation created successfully."
				));
			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave Allocation."
				));
			}
		}
	}

	function AJAX_updateAllocation() {
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_allocation', $data, array('id'=>$id));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Allocation."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_deleteAllocation()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_allocation', $data, array('id'=>$data['id']));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Allocation deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Allocation."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_createApplication()	{
		$data = $this->input->post();

		if ($data) {
			$user_name  = $data['user_name'];
			$leave_name = $data['leave_name'];

			unset($data['user_name']);
			unset($data['leave_name']);

			$date_from  = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
			$date_to	= new DateTime(date('Y-m-d', strtotime($data['date_to'])));

			$next_date_from = new DateTime(date('Y-m-d', strtotime('+1 day', strtotime($data['date_from']))));
			$prev_date_to 	= new DateTime(date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))));

			$half_day = 0.5;

			// COUNT DAYS APPLIED
			if($data['type_id'] == 5){ //maternity leave calculate include weekend
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDaysIncludeWeekend($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDaysIncludeWeekend($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}else{
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDays($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDays($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}
			
			if ($data['days_applied'] > 0) {
				$data['date_from'] 	= date('Y-m-d', strtotime($data['date_from']));
				$data['date_to'] 	= date('Y-m-d', strtotime($data['date_to']));
				$data['created_by'] = $this->logged_user['id'];

				$id = $this->model_general->insert('hr__leave_application', $data);

				if(isset($_FILES['attachment'])) {
					$data_attachment 			       = $this->upload("attachment", "attachment", 'hr/leave/'.$data['user_id'].'/');
					$data_attachment['application_id'] = $id;
					$data_attachment['user_id']		   = $data['type_id'];
					$data_attachment['created_by']     = $this->logged_user['id'];

					$attachment_id = $this->model_general->insert('hr__leave_attachment', $data_attachment);
				}

				if($id) {
					$filters = array(
						'd.department_id = '.$data['department_id'],
						'c.module_id = 4',
						'c.access_lvl != "user"'
					);
			
					$admins = $this->model_user->getUsersEmails($filters);
					
					if ($admins) {
						// SEND EMAIL TO DEPARTMENT MANAGERS
						$email_data['subject'] = 'New Leave Application';
						$email_data['message'] = $user_name.' has applied '.$leave_name.' for '.$data['days_applied']. ' day(s) from '.date('l',strtotime($data['date_from'])).', '.date('d/m/Y',strtotime($this->input->post('date_from'))).', to '.date('l',strtotime($this->input->post('date_to'))).', '.date('d/m/Y',strtotime($this->input->post('date_to'))).'. Please review this leave application accordingly.';
						$email_data['emails']  = [];
						
						foreach($admins as $admin) array_push($email_data['emails'], ($admin['primary_email']) ? $admin['primary_email'] : (($admin['secondary_email']) ? $admin['secondary_email'] : $admin['email']));
						
						// var_dump($email_data);
						// exit();
						
						$this->load->library('email');
						$this->load->library('parser');
						$this->load->library('encrypt');
			
						$email_template = $this->load->view("template/email/header", "", true);
						$email_template .= $this->load->view("template/email/body/leave", $email_data, true);
						$email_template .= $this->load->view("template/email/footer", "", true);
			
						$this->email->from('support@iziwizi.io','support@spserp')
									->to($email_data['emails'])
									->subject('New Leave Application')
									->message($email_template)
									->set_mailtype("html");
										
						$send = $this->email->send(); 

						$logEmail['userID']=$this->session->userdata('user')['id'];
						$logEmail['to']= implode(' ',$email_data['emails']);
						$logEmail['result']= $send;
						$logEmail['text']= print_r($this->email,true);
						$this->db->insert('_log__email',$logEmail);

						if ($send) {
							print json_encode(array(
								"status" => "Success",
								"msg"	 => "Leave Application created and e-mailed successfully."
							));

						} else {
							print json_encode(array(
								"status" => "Success",
								"msg"	 => "Leave Application created successfully but failed to e-mail to the correct channels."
							));
						}

					} else {
						print json_encode(array(
							"status" => "Success",
							"msg"	 => "Leave Application created successfully."
						));
					}
						
					
				} else {
					print json_encode(array(
						"status" => "Error",
						"msg"	 => "System failed to create Leave Application."
					));
				}
			} else {
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to create Leave Application."
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function AJAX_checkLeave() {
		$data = $this->input->post(); //user_id, date from to, leave type, days applied
		if(empty($data['user_id']) || empty($data['date_from']) || empty($data['date_to']) || empty($data['days_applied'])  || empty($data['leave_type']) ){
		}
		
		$userDetail = $this->model_user->getUsers($data['user_id']);
		
		if ($data) {
			$prorate = $this->getProRate($data['user_id'], $data['date_from']);

			if ($data['date_from'] && $data['date_to']) {
				$date_from = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
				$date_to	 = new DateTime(date('Y-m-d', strtotime($data['date_to'])));

				$next_date_from = new DateTime(date('Y-m-d', strtotime('+1 day', strtotime($data['date_from']))));
				$prev_date_to = new DateTime(date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))));

				$half_day = 0.5;
				
				// COUNT DAYS APPLIED
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDays($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDays($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}

			if ($prorate) {
				$respond = array('status'  => 'success', 'prorate' => $prorate);

				if ($data['days_applied']) $respond['days_applied'] = $data['days_applied'];

				print json_encode($respond);
			} else {
				print json_encode(array('status' => 'failed'));
			}
		} else {
			print json_encode(array('status' => 'failed'));
		}
	}
	function AJAX_checkAllocation() {
		$data = $this->input->post(); //user_id, date from to, leave type, days applied
		$result = array();
		if(empty($data['user_id']) || empty($data['date_from']) || empty($data['date_to']) || empty($data['days_applied'])  || empty($data['leave_type']) ){
			$result['errorMesg'] = 'User ID or Leave Type are empty';
		}
		
		$allocation = $this->model_general->fetchSingle('hr__leave_allocation', array('*'), $where = array(), $join = array(), $order = array()); 
		if ($data) {
			$prorate = $this->getProRate($data['user_id'], $data['date_from']);

			if ($data['date_from'] && $data['date_to']) {
				$date_from = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
				$date_to	 = new DateTime(date('Y-m-d', strtotime($data['date_to'])));

				$next_date_from = new DateTime(date('Y-m-d', strtotime('+1 day', strtotime($data['date_from']))));
				$prev_date_to = new DateTime(date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))));

				$half_day = 0.5;
				
				// COUNT DAYS APPLIED
				if ($data['period_from_id'] == 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($date_from, $date_to);
				} else if ($data['period_from_id'] == 1 && $data['period_to_id'] != 1) {
					$data['days_applied']	= $this->countDays($date_from, $prev_date_to);
					$data['days_applied']	+= $half_day;
				} else if ($data['period_from_id'] != 1 && $data['period_to_id'] == 1) {
					$data['days_applied']	= $this->countDays($next_date_from, $date_to);
					$data['days_applied']	+= $half_day;
				} else {
					if($date_from == $date_to) {
						$data['days_applied']  = $half_day;
					} else {
						$data['days_applied']	= $this->countDays($next_date_from, $prev_date_to);
						$data['days_applied']   += ($data['period_from_id'] == $data['period_to_id']) ? 1 : $half_day;
					}
				}
			}

			if ($prorate) {
				$respond = array('status'  => 'success', 'prorate' => $prorate);

				if ($data['days_applied']) $respond['days_applied'] = $data['days_applied'];

				print json_encode($respond);
			} else {
				print json_encode(array('status' => 'failed'));
			}
		} else {
			print json_encode(array('status' => 'failed'));
		}
	}

	function AJAX_getSelfAllocation(){
		$data = $this->input->post();
		
		if(empty($data['year'])) print json_encode(array('status' => 'failed'));
		else {
			$data['user_id'] = $this->logged_user['id'];
			$rs = $this->model_leave->getSelfAllocationSetup($data);
			print json_encode(array('status' => 'success',
				'sql'=> $this->db->last_query(),
				'rs' => $rs));
		}
	}
/*	// function allocation_summary($year=null, $user_id=null) {
	// 	$data = array(
	// 		'page_setup'  => $this->template->pageSetup('HR', '', 'Staff Allocation Summary'),
	// 		'staffs' 	  => $this->model_user->getUsers(),
	// 		'allocations' => $this->model_leave->getAllocation()
	// 	);

	// 	$this->template->view('hr/leave/summary', $data);
	// }

	// function application_history($year=null, $user_id=null) {
	// 	$year = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');

	// 	$data = array(
	// 		'page_setup'  => $this->template->pageSetup('HR', '',  $year. ' Staff Application History'),
	// 		'staffs' 	  => $this->model_user->getUsers(),
	// 		'allocations' => $this->model_leave->getAllocation()
	// 	);

	// 	if ($user_id) $data['user'] = $this->model_user->getUsers($user_id);

	// 	($user_id) ? $this->template->view('hr/leave/userSummary', $data) : $this->template->view('hr/leave/summary', $data);
	// } */

	// sn
	function application_v3($user_id=null, $year=null, $mode='default') {
		log_message('error', 'application_v3');

		$user_id 	  	   = ($user_id && strtolower($this->logged_module['role']) != 'user') ? $user_id : $this->logged_user['id'];
		$year 	 	  	   = ($year && $this->validateDate($year, 'Y')) ? $year : date('Y');
		$data['years'] 	   = $this->model_leave->getEntitlementYears();
		$data['curr_year'] = $year;
		$data['user'] 	   = $this->model_user->getUsers($user_id);
		$data['user_id'] 	   = $user_id; 
		$data['mode'] = $mode; 

		log_message('error', 'user id: ' . $user_id);    

		if($mode == 'print') {
			$print_data = array(
				'title'   => strtoupper($data['user']['name']).'\'S LEAVE APPLICATION LIST REPORT FOR THE YEAR '.$year,
				'headers' => array('Applicant', 'Date From', 'Date To', 'Days', 'Leave Type', 'Status', 'Relief Person'),
				'body' 	  => $this->model_leave->getApplication(array('a.user_id' => $data['user']['id'], 'year(a.date_from) >=' => $year), null, 'print'),
			);

			$this->report_template($print_data);
		} else {
			$data['today']			= new DateTime(date('Y-m-d'));
			$data['year']			= $year;
			$data['relief_persons'] = $this->model_user->getUsersByFilter(null);

			// get leave types and their allocations
			// $data['allocations']  	= $this->model_leave->getAllocationCurrentYear(array('a.user_id' => $data['user_id']));
			$data['allocations']  	= $this->model_leave->getAllocation4(array('a.user_id' => $data['user_id'], 'a.year' => $year)); 
			// for each leave type, get all applications
			if(count($data['allocations']) > 0){
				$a = 0;
				foreach($data['allocations'] as $alloc){
					log_message('error', 'fetching applications for ' . $alloc['type_id']);
					$apps = $this->model_leave->getApplication3(
						array('a.user_id' => $data['user_id'], 'year(a.date_from) >=' => $year, 'a.type_id' => $alloc['type_id']));
					$tda = 0;
					foreach($apps as $app){
						$tda += $app['days_applied'];
					}
					log_message('error', $alloc['name'] . ' applied: ' . $tda);
					if($alloc['is_prorate'] == 1){
						// calculate prorated leave. less than 1y vs >1y
						log_message('error', 'year joined: ' . date('Y', strtotime($data['user']['date_joined'])));
						if((date_diff(date_create(date('Y-m-d')), date_create($data['user']['date_joined']))->format('%a') < 365) && (date('Y', strtotime($data['user']['date_joined'])) == date('Y'))){
							$data['allocations'][$a]['balance_entitled_'] = ($alloc['leave_entitled'] / 12 * (date('n') - date('n', strtotime($data['user']['date_joined']))));
							$data['allocations'][$a]['balance_entitled_deducted'] = ($alloc['leave_entitled'] / 12 * (date('n') - date('n', strtotime($data['user']['date_joined'])))) - $tda;
						}else{
							$data['allocations'][$a]['balance_entitled'] = ($alloc['leave_entitled'] / 12 * date('n'));
							$data['allocations'][$a]['balance_entitled_deducted'] = ($alloc['leave_entitled'] / 12 * date('n')) - $tda;
						}
					}else{
						// $data['allocations'][$a]['balance_entitled'] = $alloc['leave_balance'];
						$data['allocations'][$a]['balance_entitled'] = $alloc['leave_entitled'];
						$data['allocations'][$a]['balance_entitled_deducted'] = $alloc['leave_balance'];
						// $data['allocations'][$a]['balance_entitled_deducted'] = $alloc['leave_balance'] - $tda;
					}
					// $data['allocations'][$a]['balance_entitled'] = 
					// 	$alloc['is_prorate'] == 1 ? (($alloc['leave_entitled'] / 12 * date('n')) - $tda) : $alloc['leave_balance'];
					$data['allocations'][$a]['applications'] = $apps;
					// $alloc['balance_entitled'] = $alloc['is_prorate'] == 1 ? (($alloc['leave_entitled'] / 12 * date('n')) - $alloc['days_applied']) : $alloc['leave_balance'];
					// $data['allocations'][$a]['applications']
					$a++;
				}
			}

			$data['applications'] 	= $this->model_leave->getApplication(array('a.user_id' => $data['user_id'], 'year(a.date_from) >=' => $year));
			$data['leave_info'] 	= $this->model_leave->getLeaveInfo(array('user_id = ' => $data['user_id'], 'year(date_from) = ' => $year));
			$data['leave_types'] 	= $this->model_leave->getLeaveType();
			$data['leave_periods'] 	= $this->model_leave->getRefPeriod();
			// $data['prorate']		= $this->getProRate($user_id,NULL,$mode);
			// $data['exam_list']		= $this->model_exam->get_valid_exam_list_by_user($user_id);
			$data['exam_list']		= $this->model_exam->getValidExamListByUser($user_id);
			$data['page_setup'] 	= $this->template->pageSetup('HR', '', 'Leave Application '.$year);

			// get public holidays based on state
			$data['public_holidays'] = $this->model_leave->getPublicHoliday($data['user']['state']);
			$this->template->view('hr/leave_V2/application_v2', $data);
		}
	}

	// sn
	function createApplication2()	{
		log_message('error', 'createApplication@Leave_v3');
		$data = $this->input->post();

		if ($data) {
			try{
				// data processing
				$user_name  = $data['user_name'];
				$leave_name = $data['leave_name'];
	
				$date_from  = new DateTime(date('Y-m-d', strtotime($data['date_from'])));
				$date_to	= new DateTime(date('Y-m-d', strtotime($data['date_to'])));

				unset($data['user_name']);
				unset($data['leave_name']);

				log_message('error', 'date from: ' . $data['date_from']);
				log_message('error', 'date to: ' . $data['date_to']);
				log_message('error', 'leave duration: ' . $data['days_applied']);
				log_message('error', 'post date-processing');
	
				if ($data['days_applied'] > 0) {
					$data['date_from'] 	= date('Y-m-d', strtotime($data['date_from']));
					$data['date_to'] 	= date('Y-m-d', strtotime($data['date_to']));
					$data['created_by'] = $this->logged_user['id'];

					log_message('error', 'date from: ' . $data['date_from'] . ' date to: ' . $data['date_to']);
	
					// add application
					$id = $this->model_general->insert('hr__leave_application', $data);
					log_message('error', 'new application id inserted: ' . $id);

					// update allocation
					$updateQ = 'update hr__leave_allocation set leave_taken = leave_taken + ?, balance_entitled = balance_entitled - ?, 
						leave_balance = leave_balance - ? where id = ?';
					$this->db->query($updateQ, array($data['days_applied'], $data['days_applied'], $data['days_applied'], $data['allocation_id']));

					if(isset($_FILES['attachment'])) {
						log_message('error', 'processing attachment');
						$data_attachment 			       = $this->upload("attachment", "attachment", 'hr/leave/'.$data['user_id'].'/');
						$data_attachment['application_id'] = $id;
						$data_attachment['user_id']		   = $data['type_id'];
						$data_attachment['created_by']     = $this->logged_user['id'];
	
						$attachment_id = $this->model_general->insert('hr__leave_attachment', $data_attachment);
						log_message('error', 'new attachment id inserted: ' . $attachment_id);
					}
	
					if($id) {
						$filters = array(
							'd.department_id = '.$data['department_id'],
							'c.module_id = 4',
							'c.access_lvl != "user"'
						);
				
						$admins = $this->model_user->getUsersEmails($filters);
						
						if ($admins) {
							log_message('error', 'local. skipping email');
							$send = true;

							// SEND EMAIL TO DEPARTMENT MANAGERS
							// $email_data['subject'] = 'New Leave Application';
							// $email_data['message'] = $user_name.' has applied '.$leave_name.' for '.$data['days_applied']. ' day(s) from '.date('l',strtotime($data['date_from'])).', '.date('d/m/Y',strtotime($this->input->post('date_from'))).', to '.date('l',strtotime($this->input->post('date_to'))).', '.date('d/m/Y',strtotime($this->input->post('date_to'))).'. Please review this leave application accordingly.';
							// $email_data['emails']  = [];
							
							// foreach($admins as $admin) array_push($email_data['emails'], ($admin['primary_email']) ? $admin['primary_email'] : (($admin['secondary_email']) ? $admin['secondary_email'] : $admin['email']));
							
							// $this->load->library('email');
							// $this->load->library('parser');
							// $this->load->library('encrypt');
				
							// $email_template = $this->load->view("template/email/header", "", true);
							// $email_template .= $this->load->view("template/email/body/leave", $email_data, true);
							// $email_template .= $this->load->view("template/email/footer", "", true);
				
							// $this->email->from('support@iziwizi.io','support@spserp')
							// 			->to($email_data['emails'])
							// 			->subject('New Leave Application')
							// 			->message($email_template)
							// 			->set_mailtype("html");
											
							// $send = $this->email->send(); 

							// log_message('error', 'post sending email. storing log');
	
							// $logEmail['userID']=$this->session->userdata('user')['id'];
							// $logEmail['to']= implode(' ',$email_data['emails']);
							// $logEmail['result']= $send;
							// $logEmail['text']= print_r($this->email,true);
							// $this->db->insert('_log__email',$logEmail);

							log_message('error', 'all good');
	
							if ($send) {
								print json_encode(array(
									"status" => "Success",
									"msg"	 => "Leave Application created and e-mailed successfully."
								));
	
							} else {
								print json_encode(array(
									"status" => "Success",
									"msg"	 => "Leave Application created successfully but failed to e-mail to the correct channels."
								));
							}
	
						} else {
							print json_encode(array(
								"status" => "Success",
								"msg"	 => "Leave Application created successfully."
							));
						}
							
						
					} else {
						print json_encode(array(
							"status" => "Error",
							"msg"	 => "System failed to create Leave Application."
						));
					}
				} else {
					print json_encode(array(
						"status" => "Error",
						"msg"	 => "System failed to create Leave Application."
					));
				}
			}catch(Exception $e){
				log_message('error', 'error creating application: ' . $e->getMessage());
				print json_encode(array(
					'status' => 'Error',
					'msg' => 'Failed to create leave application'
				));
			}
		} else {
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	// sn
	function deleteApplication2()	{
		$data = $this->input->post();
		log_message('error', 'deleting application with id: ' . $data['id']);
		if(isset($data['id']))
		{
			$data['is_delete']  = 1;
			$data['deleted_by'] = $this->logged_user['id'];
			$data['deleted_ts'] = date('Y-m-d H:i:s');
			
			// get detail
			$app = $this->db->select('*')->from('hr__leave_application')->where('id', $data['id'])->get()->row();
			log_message('error', 'deleting application with days applied: ' . $app->days_applied);

			// update application
			$ok = $this->model_general->update('hr__leave_application', $data, array('id'=>$data['id']));

			// update allocation
			$updateQ = 'update hr__leave_allocation set leave_taken = leave_taken - ?, balance_entitled = balance_entitled + ?, 
						leave_balance = leave_balance + ? where id = ?';
			$updateOk = $this->db->query($updateQ, array($app->days_applied, $app->days_applied, $app->days_applied, $app->allocation_id));
			log_message('error', 'update: ' . $updateOk);

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application deleted successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "Failed to delete Leave Application."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}

	function updateApplication2()	{
		$data = $this->input->post();

		if(isset($data['id']))
		{
			$id = $data['id'];
			unset($data['id']);

			$data['updated_by'] = $this->logged_user['id'];
			$data['updated_ts'] = date('Y-m-d H:i:s');

			$ok = $this->model_general->update('hr__leave_application', $data, array('id'=>$id));

			if($ok)
			{
				print json_encode(array(
					"status" => "Success",
					"msg"	 => "Leave Application updated successfully."
				));
			}
			else
			{
				print json_encode(array(
					"status" => "Error",
					"msg"	 => "System failed to update Leave Application."
				));
			}
		}
		else
		{
			print json_encode(array(
				"status" => "Error",
				"msg"	 => "Data is missing."
			));
		}
	}
	
}