<?php
function grade_per($grade, $user){
	if ($user['Role']['grade'] > $grade){
		return false;
	}else{
		return true;
	}
}

function getMonths(){
	return  array(
    '01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April',
    '05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August',
    '09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December',
	);
}

function expence_types(){
	return  array('Redemption' => 'Redemption', 'Sampling' =>'Sampling', 'D&D'=>'D&D');
}

function BikesupervisorChecklist(){
	return  array('customer_existence' => 'Customer Existence', 'met_with_customer' =>'Met With Customer', 'route_compliance'=>'Route Compliance', 'product_display' => 'Product Display', 'promo_awareness' =>'Promo Awareness', 'outstanding_redemption'=>'Outstanding Redemption', 'incentive_issuance' => 'Incentive Issuance', 'yes_available' =>'YES Available', 'pf_available'=>'PF Available', 'as_available'=>'AS Available', 'asm_available' => 'ASM Available');
}
function get_units($key = ''){
	$units = array('Case'=>'Case', 'Roll'=>'Roll', 'Pack'=>'Pack');
	if ($key){
		return $units[$key];
	}else{
		return $units;
	}
}

/*** default all expenses posted by users from these two depots (Sokoto 2- Dosso and Kano 2- Maradi) only to report on one Brand “AllStars Niger Retail” - $brand_id = 14. And For Other depots “Yes Consumer” - $brand_id = 1 ***/
function get_expense_brand_id($depot_id = ''){
		$brand_id = 1; 
	if($depot_id == SOKOTO2DOSSO || $depot_id == KANO2MARADI){
		$brand_id = 14; 
	}
	
	return $brand_id;
}

/* function getaddress($lat,$lng){
	$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.trim($lat).','.trim($lng).'&sensor=false';
	$json = @file_get_contents($url);
	$data=json_decode($json);
	$status = $data->status;
	if($status=="OK")
		return $data->results[0]->formatted_address;
	else
		return false;
} */

function getaddress($lat,$long){
	
	$id = HERE_APP_ID;
	$cod = HERE_APP_CODE;
	
	$here = json_decode ( file_get_contents ("https://reverse.geocoder.api.here.com/6.2/reversegeocode.json?prox=".$lat."%2C".$long."%2C250&mode=retrieveAddresses&maxresults=1&gen=9&app_id=".HERE_APP_ID."&app_code=".HERE_APP_CODE), true); //pr($here);

	$start_location = $here["Response"]["View"][0]["Result"][0]["Location"]["Address"]["Label"];  

	return $start_location;
}

/* function distance($lat1, $lon1, $lat2, $lon2, $unit) {

	$theta = $lon1 - $lon2;
	$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
	$dist = acos($dist);
	$dist = rad2deg($dist);
	$miles = $dist * 60 * 1.1515;
	$unit = strtoupper($unit);
	
	if ($unit == "K") {
		return number_format(($miles * 1.609344), 3);
	} else if ($unit == "N") {
		return number_format(($miles * 0.8684), 3);
	} else {
		return number_format($miles, 3);
	}
} */

/******** Haversine Formula Version ********
 Key Improvements
 - More accurate than spherical law of cosines, especially for small distances.
 - Uses Earth's radius directly in miles, kilometers, or nautical miles.
 - Uses default unit as miles if none or invalid unit is provided.
 - Simple and readable. 
/********  ********/
function distance($lat1, $lon1, $lat2, $lon2, $unit = 'K') {
    // Convert degrees to radians
    $lat1 = deg2rad($lat1);
    $lon1 = deg2rad($lon1);
    $lat2 = deg2rad($lat2);
    $lon2 = deg2rad($lon2);

    // Radius of Earth in different units
    $earthRadius = [
        'K' => 6371.0,    // kilometers (default)
        'M' => 3958.8,    // miles
        'N' => 3440.1     // nautical miles
    ];

    // Haversine formula
    $dlat = $lat2 - $lat1;
    $dlon = $lon2 - $lon1;

    $a = sin($dlat / 2) * sin($dlat / 2) +
         cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2);

    $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

    // Validate and use unit (default to kilometers)
    $unit = strtoupper($unit);
    $radius = !empty($earthRadius[$unit]) ? $earthRadius[$unit] : $earthRadius['K'];

    $distance = $radius * $c;

    return number_format($distance, DECIMAL_NUMBER_FORMAT); // 2 decimal places
}

function incentive_type(){
	return array('Redemption' => 'Redemption', 'Sampling'=>'Sampling', 'D&D'=>'D&D','Customer on Target'=>'Customer on Target', 'Dist. Incentive'=>'Dist. Incentive');
}

function vStatus($id = null){
	$status =  array('1'=>'Verified', '0'=>'Unverified');
	if($id !== null){
		return $status[$id];
	}else{
		return $status;
	}
}

function timeStr($duration = 0){
	$secs = (int)$duration;
	$units = array(
                "week"   => 7*24*3600,
                "day"    =>   24*3600,
                "hour"   =>      3600,
                "minute" =>        60,
                "second" =>         1,
        );

	// specifically handle zero
	if ( $secs == 0 ) return "0 seconds";

	$s = "";

	foreach ( $units as $name => $divisor ) {
		if ( $quot = intval($secs / $divisor) ) {
			$s .= "$quot $name";
			$s .= (abs($quot) > 1 ? "s" : "") . ", ";
			$secs -= $quot * $divisor;
		}
	}

	return substr($s, 0, -2);
}

function getMonth($key = null){
	$months =  array("01"=>"January", "02"=>"February", "03"=>"March","04"=>"April","05"=>"May","06"=>"June","07"=>"July", "08"=>"August", "09"=>"September","10"=>"October","11"=>"November","12"=>"December");
	
	if($key && isset($months[$key])){
		return $months[$key];
	}else{
		return $months;
	}
}
function inactive_status($key = 0){
	$in_status = array('3'=>'RESIGNED', '4'=>'FIRED', '5'=>'TERMINATION');
	if($key && isset($in_status[$key])){
		return $in_status[$key];
	}else{
		return $in_status;
	}
}
/*function getWeek($key = null){
	$week =  array("01"=>__("Monday"), "02"=>__("Tuesday"), "03"=>__("Wednesday"),"04"=>__("Thursday"),"05"=>__("Friday"),"06"=>__("Saturday"),"00"=>__("Sunday"));
	
	if($key && isset($week[$key])){
		return $week[$key];
	}else{
		return $week;
	}
}*/

function getWeek($key = null){
	$week =  array("Monday"=>__("Monday"), "Tuesday"=>__("Tuesday"), "Wednesday"=>__("Wednesday"),"Thursday"=>__("Thursday"),"Friday"=>__("Friday"),"Saturday"=>__("Saturday"),"Sunday"=>__("Sunday"));
	
	if($key && isset($week[$key])){
		return $week[$key];
	}else{
		return $week;
	}
}


function getComment($key = null){
	$comment = array('1'=>'Free issue', '2'=>'Sampling', '3'=>'Customer on target','4'=>'Redemption');
	
		if($key && isset($comment[$key])){
			return $comment[$key];
		}else{
			return $comment;
		}
}

function listWeek($key = null){
//	$week =  array("1"=>__("First Week"), "2"=>__("Second Week"), "3"=>__("Third Week"),"4"=>__("Fourth Week"),"5"=>__("Fifth Week"),"6"=>_("Sixth Week"));
	
	$week =  array("1"=>__("First Week"), "2"=>__("Second Week"), "3"=>__("Third Week"),"4"=>__("Fourth Week"));
	
	if($key && isset($week[$key])){
		return $week[$key];
	}else{
		return $week;
	}
}

/***********
 - Returns the week number of the given date within the month, considering:
	- Weeks go Monday to Sunday
	- A Sunday falls into the next week 
***********/
function weekOfMonth($qDate) {
    $dt = strtotime($qDate);
    $day  = date('j',$dt);
    $month = date('m',$dt);
    $year = date('Y',$dt);
    $totalDays = date('t',$dt);
    $fdm = date("N", mktime(0,0,0,$month,1,$year));
    $weekCnt = 1;
    $retWeek = 0;
    for($i=1;$i<=$totalDays;$i++) {
        $curDay = date("N", mktime(0,0,0,$month,$i,$year)); // Day of week (1-7)
		//1 = Monday, 2 = Tuesday, ... , 7 = Sunday
		
        if ($i==1 && $fdm == 7){
			$retWeek = $weekCnt; // First day is Sunday = still considered in Week 1
		}
        elseif ($curDay==7) { // If it's Sunday
            if($i==$day) {
                $retWeek = $weekCnt+1; // The date is Sunday, so it's part of next week
            }
            $weekCnt++; // Move to next week
        } else {
            if($i==$day) {
                $retWeek = $weekCnt; // For normal days (Mon-Sat)
            }
        }
    }
    return $retWeek;
}

function getY3Week($date=null){
		if(!empty($date)){
			$d = weekOfMonth($date); 
		}else{
			$d = weekOfMonth(date('Y-m-d')); 
		}
		
		
		$lastDayPrev = date('Y-m-d', strtotime('last day of previous month')); //pr($lastDayPrev);
		$dPrev = weekOfMonth($lastDayPrev); //pr($dPrev);
		
		
		 
		$firstday =date('D', strtotime(date('Y-m-01'))); //pr($firstday);
		
		/* If the previous month had 5 or 6 weeks and the current month starts on a Sunday, then:
		It bumps the week number ($d) by 1 or 2. */
		
		if($dPrev == 5 && $firstday == 'Sun'){
			/* $week += 1; */
			$d += 1;
		}elseif($dPrev == 6 && $firstday == 'Sun'){
			/* $week += 2; */
			$d += 2;
		} 

		
		if ($d == 5) {
			$week = 1;
		  } elseif ($d == 6) {
			 $week = 2; 
		  } else {
			 $week = $d; 
		 }
		//pr('CRM week no. - '.$week);
		
		return $week;
}

//FOR Y3- brand_group_id AND For other crm Change fucntion to brand_id
	function calStickQty($brand_group_id, $qty){
		
		
		$branddb=  ClassRegistry::init('Brand');
		
		/* $brand = $this->query("SELECT * FROM brands as Brand WHERE id = $brand_id  LIMIT 0,1"); //pr($brand); */
		
		$brand = $branddb->find('all', array('conditions'=>array('brand_group_id'=>$brand_group_id)));
		//pr($brand);
		
		$qty = $qty * $brand[0]['Brand']['case_roll'] * $brand[0]['Brand']['roll_pack'] * $brand[0]['Brand']['pack_sticks'];
		
		return $qty; 
	}
	
	

function getVisits(){
    return  array(
        '0' => __('Zero'),'1' => __('Once'), '2' =>  __('Twice'), '3' =>  __('3 or More than 3 times')
    );
}

function customerVisitYearTables($from=null, $to=null){
    $cvisityear_tables = array();
    $tablestartyear = 2012;
    if (!empty($from)){
        $date = $from;
    }else{
        $date = date('Y-m-d');
    }

    if (!empty($to)){
        $date2 = $to;
    }else{
        $date2 = date('Y-m-d');
    }

    if(strtotime($date) <= strtotime($date2)){
        $year1 = date('Y', strtotime($date));
        $year2 =  date('Y', strtotime($date2));
    }else{
        $year1 = date('Y', strtotime($date2));
        $year2 = date('Y', strtotime($date));
    }

    if($year1 != $year2){
        for($i=$year1;$i<=$year2;$i++){
            if($i < $tablestartyear || $i > date('Y')){
                continue;
            }
            if(($i == date('Y'))){

                if($i == date('Y')){
                    $cvisityear_tables[$i] = 'customer_visits';
                }
            }else{
                $cvisityear_tables[$i] = 'customer_visits_'.$i;
            }
        }
    }else{
        if($year1 == date('Y' ) || $year1 < $tablestartyear || $year1 > date('Y')){
            $cvisityear_tables[$year1] = 'customer_visits';
        }else{
            $cvisityear_tables[$year1] = 'customer_visits_'.$year1;
        }
    }

    if(empty($cvisityear_tables)){
        $cvisityear_tables[$year1] = 'customer_visits';
    }

    $cvisityear_tables = array_unique($cvisityear_tables);

    return $cvisityear_tables;

}


function getEntityName($model, $id){
	$table=  ClassRegistry::init($model);
	
	if($model=='Customer'){
		$title = $table->find('list', array('fields'=>array('id', 'name'),'conditions'=>array('id'=>$id)));
	}elseif($model=='State'){
		$title = $table->find('list', array('fields'=>array('id', 'state'),'conditions'=>array('id'=>$id)));
	}else{
		$title = $table->find('list', array('conditions'=>array('id'=>$id))); 
	}
	
	return !empty($title[$id]) ? $title[$id] : '' ; 
}

function getbrandGroups(){
	$brandGroup=  ClassRegistry::init('BrandGroup');
	$brandGroups = $brandGroup->find('list', array('fields'=>array('id', 'name')));
	
	return $brandGroups;
}

function getExcludedUserRolesForSale(){
	// r.grade > 3
	return  [ADMINISTRATOR, HMS, SUPPORTTEAM1, SUPPORTTEAM2, PROMO, DIVISIONMANAGER, RM];
}

function getExcludedUserRolesForVisit(){
	// web / support roles
	return  [ADMINISTRATOR, HMS, SUPPORTTEAM1, SUPPORTTEAM2, PROMO];
}

function get_client_ip(){
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    } else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else if (isset($_SERVER['HTTP_X_FORWARDED'])) {
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    } else if (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    } else if (isset($_SERVER['HTTP_FORWARDED'])) {
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    } else if (isset($_SERVER['REMOTE_ADDR'])) {
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    } else {
        $ipaddress = 'UNKNOWN';
    }

    return $ipaddress;
}


function getStatus($key = null){
    $a_status =  array(
        '1' => __('Active'),'0' => __('Inactive'), '2' =>  __('Discontinued'), '3' =>  __('Disposed')
    );
	if($key && isset($a_status[$key])){
		return $a_status[$key];
	}else{
		return $a_status;
	}
}




/************************** PTG calendar START **************************/	

function calendar($wk1_start , $wk1_end ){
	$year = date('Y', strtotime($wk1_start));

	$date = $wk1_start;
	
	for($month=1; $month<= 12; $month++ ){
		$firstDate = $year.'-'.$month.'-01';
		$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, intval($year)); 
		$last_date = date("Y-m-t", strtotime($firstDate)); 
		
		$week = 1; 
		while (strtotime($date) <= strtotime($last_date)) {
			
			if($month==1 && $week == 1){ 
				
				//Get first week of JAN
				while (strtotime($date) <= strtotime($wk1_end)) {
					
					if(empty($calendar[$month][$week])){
						$calendar[$month][$week][] = $date;
					}else{
						array_push($calendar[$month][$week],$date);
					}
					
					$date = date('Y-m-d', strtotime($date . ' +1 day'));
					
				}
				
				$week ++;
			}elseif ($month == 7 && $week == 1){				
				$extraDays = 7 - $extraDaystolastWeekofJun;
				if($extraDays < 4){
					for($i=1; $i<= (7+$extraDays); $i++){ 
						$calendar[$month][$week][] = $date; 
						$date = date('Y-m-d', strtotime($date . ' +1 day'));
					}
				}else{
					for($i=1; $i<= $extraDays; $i++){ 
						$calendar[$month][$week][] = $date; 
						$date = date('Y-m-d', strtotime($date . ' +1 day'));
					}
				}				
				$week ++;
			}else{
				
				// IF WEEK ARRAY EXIST LOOP FOR REMAING SLOTS
				if(isset($calendar[$month][$week])){ 
					for($i=1; $i<= (7-$lastWeekDayCount); $i++){ 
						$calendar[$month][$week][] = $date;
						$date = date('Y-m-d', strtotime($date . ' +1 day'));
					}
					$week ++;
				}else{ 
					for($i=1; $i<= 7; $i++){
					
						if(strtotime($date) <= strtotime($last_date)){ 
						
							$calendar[$month][$week][] = $date;
							
							if(strtotime($date) == strtotime($last_date)){									
								$lastWeekDayCount = count($calendar[$month][$week]);
								
								
								//IF IN MONTH'S LAST WEEK DAY COUNT < 4 ? MOVE INTO NEXT MONTH'S FIRST WEEK : KEEP THE SAME WEEK 
								if($month == 6 || $month == 12){
									if($month == 6){
										//DAY COUNT OF LAST WEEK OF JUNE
										$extraDaystolastWeekofJun = count($calendar[$month][$week]); 
									}
									
									if($lastWeekDayCount < 4){ 
										$calendar[$month][$week-1] = array_merge($calendar[$month][$week-1], $calendar[$month][$week]);
										unset($calendar[$month][$week]);
									}
									
								}else{
									if($lastWeekDayCount < 4){ 
										$calendar[$month+1][1]= $calendar[$month][$week]; 	
										unset($calendar[$month][$week]);
									}else{
										//FILL REMAINING SLOTS
										$weekDayCount = count($calendar[$month][$week]); 
										for($i=1; $i<= (7-$weekDayCount); $i++){ 
											$date = date('Y-m-d', strtotime($date . ' +1 day')); 
											$calendar[$month][$week][] = $date;
										}
									}
								}
							}
						
							$date = date('Y-m-d', strtotime($date . ' +1 day'));
							
							
						}
						
						//AFTER SEVEN DAYS CREATE NEW WEEK
						if($i== 7){ 
							$week ++;
						}						
					}					
				}								
			}	
		}				
	}
	
	return $calendar;
}

function getWeekrange($monthlyCalendar){
	$weekrange = array();
	foreach($monthlyCalendar as $wno => $weekArray){ 
		$weekrange[$wno]['start'] = $weekArray[0];
		$weekrange[$wno]['end'] = $weekArray[count($weekArray) - 1];		
	}
	return $weekrange;
}

function getWeekNo($monthlyCalendar, $date){ 
	foreach($monthlyCalendar as $wno => $weekArray){ 
		if (in_array($date, $weekArray)){
			return $wno;
		}
	}
	return false;
}

function getMonthNo($calendar, $date){
	foreach($calendar as $mno => $monthlyCalendar){ 
		foreach($monthlyCalendar as $wno => $weekArray){ 
			if (in_array($date, $weekArray)){
				return $mno;
			}
		}
	}
	return false;
}

/************************** PTG calendar END **************************/	

/**
 * Determine PTG calendar period (year, month, week) for a given date
 * based on custom rules for weeks that can have more than 7 days.
 *
 * Rules:
 * 1. Normal weeks (exactly 7 days) → return current week.
 * 2. Last week of a month (>7 days):
 *    - Days 1–7 stay in this last week.
 *    - Days 8+ move to next month's week 1.
 *    - If month = December → next month = January of next year.
 * 3. First week of a month (>7 days):
 *    - Find Monday of the week.
 *    - Days before Monday → last week of previous month/year.
 *    - Days on/after Monday → week 1 of current month.
 *
 * @param string $date          Date string (Y-m-d)
 * @param array  $PTGCalendar   Calendar data containing 'year', 'month', 'week', and 'calendar'
 * @return array ['year' => int, 'month' => int, 'week' => int]
 */
function getRoutePlanPeriod($date, $PTGCalendar)
{
    $cy  = date('Y', strtotime($date)); // current year
    $cm  = $PTGCalendar['month'];       // current month
    $cw  = $PTGCalendar['week'];        // current week
    $cal = $PTGCalendar['calendar'];    // calendar data for the year

    // List of dates in the current week
    $weekDays  = $cal[$cm][$cw];
    $totalDays = count($weekDays);

    // -------------------------------------------------
    // CASE 0: Normal week (exactly 7 days)
    // No special rules → return current period
    // -------------------------------------------------
    if ($totalDays === 7) {
        return ['year' => $cy, 'month' => $cm, 'week' => $cw];
    }

    // Find position of current date in the week array (0-based index)
    $index = array_search($date, $weekDays);

    // -------------------------------------------------
    // CASE 1: Last week of the month (>7 days)
    // - Days 1–7 remain in this last week
    // - Days 8+ go to week 1 of next month/year
    // -------------------------------------------------
    $lastWeekInMonth = max(array_keys($cal[$cm]));

    if ($cw == $lastWeekInMonth) {

        // Day 8+ → next month/week 1
        if ($index > 6) {

            // December → rollover to next year January
            if ($cm == 12) {
                return [
                    'year'  => $cy + 1,
                    'month' => 1,
                    'week'  => 1
                ];
            }

            // Other months → next month, week 1
            return [
                'year'  => $cy,
                'month' => $cm + 1,
                'week'  => 1
            ];
        }

        // Days 1–7 → stay in this last week
        return ['year' => $cy, 'month' => $cm, 'week' => $cw];
    }

    // -------------------------------------------------
    // CASE 2: First week of the month (>7 days)
    // - Find Monday index in the week
    // - Days before Monday → last week of previous month/year
    // - Days on/after Monday → week 1 of current month
    // -------------------------------------------------
    if ($cw == 1) {

        // Find Monday index (0-based)
        $mondayIndex = null;
        foreach ($weekDays as $i => $day) {
            if (date('N', strtotime($day)) == 1) { // Monday = 1
                $mondayIndex = $i;
                break;
            }
        }

        // Dates before Monday → previous month
        if ($index < $mondayIndex) {

            // January → previous year December
            if ($cm == 1) {
                $prevYearDate = ($cy - 1) . "-12-31";
                $PtgCalendarTB = ClassRegistry::init('PtgCalendar');
				$setupData = $PtgCalendarTB->findByYear($cy - 1);

				$calendar = array();
				if (!empty($setupData)) {
					$wk1_start = date('Y-m-d', strtotime($setupData['PtgCalendar']['wk1_start']));
					$wk1_end   = date('Y-m-d', strtotime($setupData['PtgCalendar']['wk1_end']));
					$prevCal  = calendar($wk1_start, $wk1_end);
				}
                $lastWeekPrevDec = max(array_keys($prevCal[12]));

                return [
                    'year'  => $cy - 1,
                    'month' => 12,
                    'week'  => $lastWeekPrevDec
                ];
            }

            // Other months → previous month last week
            $prevMonth = $cm - 1;
            $lastWeekPrevMonth = max(array_keys($cal[$prevMonth]));

            return [
                'year'  => $cy,
                'month' => $prevMonth,
                'week'  => $lastWeekPrevMonth
            ];
        }

        // Dates on/after Monday → week 1 of current month
        return ['year' => $cy, 'month' => $cm, 'week' => 1];
    }

    // -------------------------------------------------
    // Fallback: Current week (safety net)
    // -------------------------------------------------
    return ['year' => $cy, 'month' => $cm, 'week' => $cw];
}


function buildDailyRouteConditions(array $dates, array $calendar, array $i_ptgPeriod){
    $dailyRouteConditions = $rpPeriodByDates = $diffRPPeriodDates = [];

    foreach ($dates as $dt) {
        $rp = getRoutePlanPeriod($dt, $calendar);

        $i_rpyear  = $rp['year'];
        $i_rpmonth = $rp['month'];
        $i_rpweek  = $rp['week'];
        $i_rpday   = date('l', strtotime($dt));

        $dailyRouteConditions[] =
            "ur.year = '$i_rpyear' AND ur.month = '$i_rpmonth' AND ur.week = '$i_rpweek' AND ur.day = '$i_rpday'";
			
		// Store period info keyed by date
        $rpPeriodByDates[$dt] = ['year'  => $i_rpyear, 'month' => $i_rpmonth, 'week' => $i_rpweek, 'day' => $i_rpday];
		
		// Check if PTG calendar period differs from route plan period
		if ($i_ptgPeriod['year']  != $i_rpyear || $i_ptgPeriod['month'] != $i_rpmonth || $i_ptgPeriod['week']  != $i_rpweek
		){
			$diffRPPeriodDates[] = $dt;
		}
    }

	return [
        'sqlConditions' 	=> $dailyRouteConditions,
        'rpPeriodByDates'   => $rpPeriodByDates,  // keyed by date
		'diffRPPeriodDates'	=> $diffRPPeriodDates
    ];
}





function getWeekForRoutePlan($w=null){
	if ($w == 5) {
		$week = 1;
	  } elseif ($w == 6) {
		 $week = 2; 
	  } else {
		 $week = $w; 
	 }
	 return $week;
}

function get_export_file_name($reportName, $dateParameter=''){
	if(!empty($dateParameter['title'])){
		$reportName .= '__' . $dateParameter['title'];
	}
	if(!empty($dateParameter['sub_title'])){
		$reportName .= '(' . $dateParameter['sub_title'].')';
	}
	return $reportName;
}

function getAssetType($key = null){
	$assetTypes = array('bike' => 'Bike', 'tricycle' => 'Tricycle', 'vehicle' => 'Vehicle');
	
		if($key && isset($assetTypes[$key])){
			return $assetTypes[$key];
		}else{
			return $assetTypes;
		}
}

function getDepartmentsForAsset(){
	return  array('Distribution' => 'Distribution', 'Sales' => 'Sales', 'Promotion' =>'Promotion', 'Supervision'=>'Supervision', 'Office'=>'Office');
}

function getCallTransferDetails($crdrtype = null, $data = array()){
	$grouped = array();
	$totalCalls = 0;
	$totalVolume = 0;

	foreach ($data as $entry) { 
		$date = $entry['date'];
		$userId = ($crdrtype == 'Debit') ? $entry['creditedTo']['id'] : $entry['debitedFrom']['id'];
		$name = ($crdrtype == 'Debit') ? $entry['creditedTo']['name'] : $entry['debitedFrom']['name'];
		$direction = ($crdrtype == 'Debit') ? 'creditedTo' : 'debitedFrom';
		$key = $date . '|' . $userId . '|' . $direction;

		if (!isset($grouped[$key])) {
			$grouped[$key] = array(
				'date' => $date,
				'user' => $name,
				'direction' => $direction,
				'types' => array()
			);
		}

		foreach ($entry['callDetails'] as $detail) {
			$typeRaw = $detail['type'];

			// Handle saleFi separately (not a counted transfer)
			if ($typeRaw === 'saleFi') {
				$fiVol = 0;
				foreach ($detail as $k => $v) {
					if ($k === 'saleFiVol') {
						$fiVol = (float)$v;
						break;
					}
				}

				$calltype = 'Sale';
				if (!isset($grouped[$key]['types'][$calltype])) {
					$grouped[$key]['types'][$calltype] = array(
						'count' => 0,
						'volume' => 0,
						'fiVolume' => 0
					);
				}

				$grouped[$key]['types'][$calltype]['fiVolume'] += $fiVol;
				$totalVolume += $fiVol;
				continue;
			}

			// Normal counted entries
			$calltype = ucfirst(preg_replace('/Entry$/', '', $typeRaw));
			$volume = 0;

			foreach ($detail as $k => $v) {
				if (strpos($k, 'Vol') !== false) {
					$volume = (float)$v;
					break;
				}
			}

			if (!isset($grouped[$key]['types'][$calltype])) {
				$grouped[$key]['types'][$calltype] = array(
					'count' => 0,
					'volume' => 0
				);

				if ($calltype === 'Sale') {
					$grouped[$key]['types'][$calltype]['fiVolume'] = 0;
				}
			}

			$grouped[$key]['types'][$calltype]['count'] += 1;
			$grouped[$key]['types'][$calltype]['volume'] += $volume;

			$totalCalls++;
			$totalVolume += $volume;
		}
	}

	// Build tooltip lines
	$lines = array();
	foreach ($grouped as $info) {
		$parts = array();
		foreach ($info['types'] as $calltype => $typedata) {
			$vol = number_format($typedata['volume'], 3);
			$label = $typedata['count'] . ' ' . $calltype . ' of ' . $vol;

			if ($calltype === 'Sale' && !empty($typedata['fiVolume'])) {
				$label .= ' (FI ' . number_format($typedata['fiVolume'], 3) . ')';
			}elseif ($calltype === 'Visit') {
                $label = $typedata['count'] . ' ' . $calltype; // Do not include volume for "Visit"
            }

			$parts[] = $label;
		}
		
		
		$directionText = ($info['direction'] == 'creditedTo') ? 'Transferred TO' : 'Transferred FROM';
		
		$lines[] = $info['date'] . ': ' . $directionText . ' User ' . $info['user'] . ' → ' . implode(', ', $parts);

		
	}

	// Add TOTAL line
	$lines[] = 'TOTAL: ' . $totalCalls . ' transfer' . ($totalCalls > 1 ? 's' : '') . ', ' . number_format($totalVolume, 3) . ' volume';

	$text = implode("\n", $lines);

	return array(
		'text' => htmlspecialchars($text),
		'totalCalls' => $totalCalls
	);
}

function getCustomerTransferDetails($data = array())
{
    $lines = array();
    $totalCalls = 0;
    $totalVolume = 0;

    foreach ($data as $entry) {

        $parts = array();

        foreach ($entry['callDetails'] as $detail) {

            $typeRaw = $detail['type'];

            if ($typeRaw === 'saleFi') {
                continue;
            }

            $calltype = ucfirst(preg_replace('/Entry$/', '', $typeRaw));

            $volume = 0;
            foreach ($detail as $k => $v) {
                if (strpos($k, 'Vol') !== false) {
                    $volume = (float)$v;
                    break;
                }
            }

            if ($calltype == 'Visit') {
                $parts[] = '1 Visit';
            } else {
                $parts[] = '1 '.$calltype.' of '.number_format($volume,3);
            }

            $totalCalls++;
            $totalVolume += $volume;
        }

        if (isset($entry['creditedTo'])) {

            $lines[] =
                $entry['date']
                .' : Transferred TO '
                .$entry['creditedTo']['name']
                .' → '
                .implode(', ', $parts);

        } elseif (isset($entry['debitedFrom'])) {

            $lines[] =
                $entry['date']
                .' : Transferred FROM '
                .$entry['debitedFrom']['name']
                .' → '
                .implode(', ', $parts);
        }
    }

    $lines[] =
        'TOTAL: '.$totalCalls
        .' transfer'.($totalCalls > 1 ? 's' : '')
        .', '.number_format($totalVolume,3).' volume';

    return array(
        'text' => htmlspecialchars(implode("\n", $lines)),
        'totalCalls' => $totalCalls
    );
}



function getCustomerCategories($key = ""){
	$categories =  array('Retailer'=>'Retailer','Stockist'=>'Stockist', 'Distributor'=>'Distributor','Consumer'=>'Consumer', 'Wholesaler'=>'Wholesaler');
	
	if($key && !empty($categories[$key])){
		return $categories[$key];
	}else{
		return $categories;
	}
}

function getGeofencedVerificationStatus(){
	return array('1'=>'Verified', '0'=>'Unverified');
}

function model_types($key = null){
	$modelTypes = array('Order'=>'Order','RedistributorSale'=>'RedistributorSale',
	'Expense'=>'Expense','Payment'=>'Payment','User'=>'User','Stock'=>'Stock',
	'Compaign'=>'Compaign','Customer'=>'Customer','UserTarget'=>'UserTarget',
	'Depot'=>'Depot','Route'=>'Route','Brand'=>'Brand',
	'CustomerVisit'=>'CustomerVisit','Incentive'=>'Incentive','ExpType'=>'ExpType');
	if($key){
		return $modelTypes[$key];
	}else{
		asort($modelTypes);
		return $modelTypes;
	}
}

/**
 * Convert case quantity to desired unit
 *
 * @param int $caseQty Quantity in cases
 * @param array $brand Brand data with keys 'case_roll', 'roll_pack', '2pack_pack'
 * @param string $selectedUnit Target unit: 'roll', 'pack', '2pack', 'case'
 * @return float Converted quantity
 */
function convertUnit($caseQty, $brand, $selectedUnit) {
    switch (strtolower($selectedUnit)) {
        case 'roll':
            return $caseQty * $brand['case_roll'];

        case 'pack':
            return $caseQty * $brand['case_roll'] * $brand['roll_pack'];

        case '2pack':
            return $caseQty * $brand['case_roll'] * $brand['roll_pack'] * $brand['2pack_pack'];

        case 'case':
        default:
            return $caseQty;
    }
}