|
Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/laciasmara.com/public_html/shop/application/helpers/ |
Upload File : |
<?php
function get_product_id($item_id)
{
$ci = &get_instance();
//get product id
$ci->db
->select('product_id')
->from('product_details')
->where('id', $item_id);
$product_id = $ci->db->get()->row()->product_id;
return $product_id;
}
function format_shipping_etd($etd, $service_type = null, $current_time = null)
{
if (empty($etd)) {
return [
'min_days' => 0,
'max_days' => 0,
'formatted_text' => 'Estimasi tidak tersedia',
'delivery_date_min' => null,
'delivery_date_max' => null,
'delivery_date_min_formatted' => null,
'delivery_date_max_formatted' => null,
'is_same_day' => false
];
}
// Set current time (for testing purposes)
$now = $current_time ? new DateTime($current_time) : new DateTime();
// Define business hours (09:00 - 17:00)
$business_start = 9; // 9 AM
$business_end = 17; // 5 PM
$pickup_cutoff = 16; // 4 PM pickup cutoff
// Determine service type
$is_instant_service = isInstantService($service_type, $etd);
$is_nextday_service = isNextDayService($service_type, $etd);
if ($is_instant_service) {
return formatInstantDelivery($etd, $now, $pickup_cutoff);
} elseif ($is_nextday_service) {
return formatNextDayDelivery($etd, $now, $pickup_cutoff);
} else {
return formatRegularDelivery($etd, $now, $pickup_cutoff);
}
}
function isWeekday($datetime)
{
$day_of_week = intval($datetime->format('w')); // 0 = Sunday, 6 = Saturday
return $day_of_week >= 1 && $day_of_week <= 5; // Monday to Friday
}
function isInstantService($service_type, $etd)
{
// Check by service type
if ($service_type) {
$instant_services = ['instant', 'gojek', 'grab'];
if (in_array(strtolower($service_type), $instant_services)) {
return true;
}
}
// Check by ETD pattern (contains "hour", "jam", or very short timeframe)
$etd_lower = strtolower($etd);
if (
strpos($etd_lower, 'hour') !== false ||
strpos($etd_lower, 'jam') !== false ||
strpos($etd_lower, 'instant') !== false
) {
return true;
}
return false;
}
function isNextDayService($service_type, $etd)
{
// Check by service type
if ($service_type) {
$nextday_services = ['next_day', 'nextday', 'oke', 'yes'];
if (in_array(strtolower($service_type), $nextday_services)) {
return true;
}
}
// Check by ETD pattern
$etd_lower = strtolower($etd);
if (
strpos($etd_lower, 'next day') !== false ||
strpos($etd_lower, 'nextday') !== false ||
$etd === '1' // ETD exactly 1 day
) {
return true;
}
return false;
}
function formatInstantDelivery($etd, $now, $pickup_cutoff)
{
// Extract time duration from ETD (e.g., "1-3 Hours" -> "1-3 Jam")
$duration_text = extractDurationText($etd);
$current_hour = intval($now->format('H'));
$is_after_cutoff = $current_hour >= $pickup_cutoff; // After 4 PM
$is_weekday = isWeekday($now);
$is_before_business = $current_hour < 9; // Before 9 AM
// Check if can deliver same day
if ($is_weekday && !$is_after_cutoff && !$is_before_business) {
// Order during business hours on weekday and before 4 PM - can deliver today
$delivery_date_min = clone $now;
$delivery_date_max = clone $now;
// For same day, add the ETD duration to current time
$min_hours = extractMinHours($etd);
$max_hours = extractMaxHours($etd);
$delivery_date_min->modify("+{$min_hours} hours");
$delivery_date_max->modify("+{$max_hours} hours");
$start_time = $delivery_date_min->format('H:i');
$end_time = $delivery_date_max->format('H:i');
$formatted_text = "Hari ini jam {$start_time}-{$end_time}";
$is_same_day = true;
} else {
// Order after 4 PM, before 9 AM, or weekend - deliver next business day
$next_business_day = getNextBusinessDay($now);
$delivery_date_min = clone $next_business_day;
$delivery_date_max = clone $next_business_day;
// Set delivery time range based on ETD duration
$min_hours = extractMinHours($etd);
$max_hours = extractMaxHours($etd);
// Start at 10 AM, then add the duration
$delivery_date_min->setTime(10, 0, 0);
$delivery_date_max->setTime(10, 0, 0);
$delivery_date_max->modify("+{$max_hours} hours");
// Calculate time range
$start_time = $delivery_date_min->format('H:i');
$end_time = $delivery_date_max->format('H:i');
$tomorrow = (clone $now)->modify('+1 day')->format('Y-m-d');
if ($next_business_day->format('Y-m-d') == $tomorrow) {
$formatted_text = "Besok jam {$start_time}-{$end_time}";
} else {
$day_name = getDayName($next_business_day);
$formatted_text = "{$day_name} jam {$start_time}-{$end_time}";
}
$is_same_day = false;
}
return [
'min_days' => 0,
'max_days' => 0,
'formatted_text' => $formatted_text,
'delivery_date_min' => $delivery_date_min->format('Y-m-d'),
'delivery_date_max' => $delivery_date_max->format('Y-m-d'),
'delivery_date_min_formatted' => $delivery_date_min->format('d M Y'),
'delivery_date_max_formatted' => $delivery_date_max->format('d M Y'),
'is_same_day' => $is_same_day
];
}
function formatNextDayDelivery($etd, $now, $pickup_cutoff)
{
$current_hour = intval($now->format('H'));
$is_after_cutoff = $current_hour >= $pickup_cutoff; // After 4 PM
$is_weekday = isWeekday($now);
$is_friday = $now->format('w') == 5; // Friday
$processing_start_date = clone $now;
// Determine processing start date
if ($is_after_cutoff || !$is_weekday) {
// Order after 4 PM or on weekend, process next business day
$processing_start_date = getNextBusinessDay($now);
}
// Next day delivery = +1 business day from processing date
$delivery_date = addBusinessDays(clone $processing_start_date, 1);
// Special case: Friday before 4 PM with next day = Saturday delivery
if ($is_weekday && !$is_after_cutoff && $is_friday) {
$delivery_date = (clone $now)->modify('+1 day'); // Saturday
}
$formatted_text = generateNextDayText($delivery_date, $now);
return [
'min_days' => 1,
'max_days' => 1,
'formatted_text' => $formatted_text,
'delivery_date_min' => $delivery_date->format('Y-m-d'),
'delivery_date_max' => $delivery_date->format('Y-m-d'),
'delivery_date_min_formatted' => $delivery_date->format('d M Y'),
'delivery_date_max_formatted' => $delivery_date->format('d M Y'),
'is_same_day' => false
];
}
function formatRegularDelivery($etd, $now, $pickup_cutoff)
{
// Parse ETD - handle both "1-2" and "1 - 2 days" formats
$etd_clean = preg_replace('/\s*days?\s*/i', '', trim($etd)); // Remove "days" word
$etd_parts = preg_split('/\s*-\s*/', $etd_clean); // Split by "-" with optional spaces
$min_days = intval($etd_parts[0]);
$max_days = count($etd_parts) > 1 ? intval($etd_parts[1]) : $min_days;
// Check if order is after cut-off time (4 PM)
$current_hour = intval($now->format('H'));
$is_after_cutoff = $current_hour >= $pickup_cutoff; // After 4 PM
$is_weekday = isWeekday($now);
$processing_start_date = clone $now;
// Determine processing start date
if ($is_after_cutoff || !$is_weekday) {
// Order after 4 PM or on weekend, process next business day
$processing_start_date = getNextBusinessDay($now);
}
// If before 4 PM on weekday, process today (keep $processing_start_date = $now)
// Calculate actual delivery dates
$delivery_date_min = clone $processing_start_date;
$delivery_date_max = clone $processing_start_date;
$delivery_date_min->modify("+{$min_days} days");
$delivery_date_max->modify("+{$max_days} days");
// Generate user-friendly formatted text
$formatted_text = generateFormattedText($min_days, $max_days, $delivery_date_min, $delivery_date_max, $now, $processing_start_date);
return [
'min_days' => $min_days,
'max_days' => $max_days,
'formatted_text' => $formatted_text,
'delivery_date_min' => $delivery_date_min->format('Y-m-d'),
'delivery_date_max' => $delivery_date_max->format('Y-m-d'),
'delivery_date_min_formatted' => $delivery_date_min->format('d M Y'),
'delivery_date_max_formatted' => $delivery_date_max->format('d M Y'),
'is_same_day' => false
];
}
function getNextBusinessDay($date)
{
$next_day = clone $date;
$next_day->modify('+1 day');
// Keep adding days until we find a weekday
while (!isWeekday($next_day)) {
$next_day->modify('+1 day');
}
// Set to business start time (9 AM)
$next_day->setTime(9, 0, 0);
return $next_day;
}
function extractDurationText($etd)
{
// Convert English duration to Indonesian
$etd_lower = strtolower($etd);
// Replace common English terms with Indonesian
$replacements = [
'hours' => 'Jam',
'hour' => 'Jam',
'minutes' => 'Menit',
'minute' => 'Menit',
'mins' => 'Menit',
'min' => 'Menit'
];
$duration = $etd;
foreach ($replacements as $english => $indonesian) {
$duration = str_ireplace($english, $indonesian, $duration);
}
// Extract numbers and duration with flexible spacing: "1 - 3 Hours" -> "1-3 Jam"
if (preg_match('/(\d+)\s*-\s*(\d+)\s*(jam|menit|hours?|minutes?)/i', $duration, $matches)) {
$min_num = $matches[1];
$max_num = $matches[2];
$unit = strtolower($matches[3]);
if (in_array($unit, ['hour', 'hours'])) {
$unit = 'Jam';
} elseif (in_array($unit, ['minute', 'minutes', 'min', 'mins'])) {
$unit = 'Menit';
} else {
$unit = ucfirst($unit);
}
return $min_num . '-' . $max_num . ' ' . $unit;
} elseif (preg_match('/(\d+)\s*(jam|menit|hours?|minutes?)/i', $duration, $matches)) {
$numbers = $matches[1];
$unit = strtolower($matches[2]);
if (in_array($unit, ['hour', 'hours'])) {
$unit = 'Jam';
} elseif (in_array($unit, ['minute', 'minutes', 'min', 'mins'])) {
$unit = 'Menit';
} else {
$unit = ucfirst($unit);
}
return $numbers . ' ' . $unit;
}
return $duration;
}
function extractMinHours($etd)
{
// Extract minimum hours from ETD for time calculation
// Handle formats like "1 - 2 Hours", "1-2 Hours", "2 Hours"
if (preg_match('/(\d+)\s*-\s*(\d+)\s*(?:hours?|jam)/i', $etd, $matches)) {
return intval($matches[1]);
} elseif (preg_match('/(\d+)\s*(?:hours?|jam)/i', $etd, $matches)) {
return intval($matches[1]);
}
return 1; // Default to 1 hour if can't parse
}
function extractMaxHours($etd)
{
// Extract maximum hours from ETD for time calculation
// Handle formats like "1 - 2 Hours", "1-2 Hours", "2 Hours"
if (preg_match('/(\d+)\s*-\s*(\d+)\s*(?:hours?|jam)/i', $etd, $matches)) {
return intval($matches[2]);
} elseif (preg_match('/(\d+)\s*(?:hours?|jam)/i', $etd, $matches)) {
return intval($matches[1]);
}
return 3; // Default to 3 hours if can't parse
}
function addBusinessDays($date, $days)
{
$added_days = 0;
while ($added_days < $days) {
$date->modify('+1 day');
// Skip weekends (Saturday = 6, Sunday = 0)
if ($date->format('w') != 0 && $date->format('w') != 6) {
$added_days++;
}
}
return $date;
}
function getDayName($date)
{
$days = [
'Sunday' => 'Minggu',
'Monday' => 'Senin',
'Tuesday' => 'Selasa',
'Wednesday' => 'Rabu',
'Thursday' => 'Kamis',
'Friday' => 'Jumat',
'Saturday' => 'Sabtu'
];
$english_day = $date->format('l');
return $days[$english_day];
}
function generateNextDayText($delivery_date, $now)
{
$today = $now->format('Y-m-d');
$tomorrow = (clone $now)->modify('+1 day')->format('Y-m-d');
$delivery_date_str = $delivery_date->format('Y-m-d');
// Next day delivery
if ($delivery_date_str == $tomorrow) {
$day_name = getDayName($delivery_date);
return "Besok";
}
$days_from_now = calculateDaysFromNow($delivery_date, $now);
if ($days_from_now == 2) {
$day_name = getDayName($delivery_date);
return "Lusa";
} elseif ($days_from_now <= 7) {
$day_name = getDayName($delivery_date);
return $day_name;
} else {
return $delivery_date->format('d M');
}
}
function calculateDaysFromNow($target_date, $now)
{
$today = clone $now;
$today->setTime(0, 0, 0);
$target = clone $target_date;
$target->setTime(0, 0, 0);
$diff = $today->diff($target);
return $diff->days;
}
function generateFormattedText($min_days, $max_days, $delivery_date_min, $delivery_date_max, $now, $processing_start_date)
{
$today = $now->format('Y-m-d');
$tomorrow = (clone $now)->modify('+1 day')->format('Y-m-d');
$min_date = $delivery_date_min->format('Y-m-d');
$max_date = $delivery_date_max->format('Y-m-d');
// Same delivery date
if ($min_date == $max_date) {
$days_from_now = calculateDaysFromNow($delivery_date_min, $now);
if ($days_from_now == 1) {
$day_name = getDayName($delivery_date_min);
return "Besok";
} elseif ($days_from_now == 2) {
$day_name = getDayName($delivery_date_min);
return "Lusa";
} elseif ($days_from_now <= 7) {
$day_name = getDayName($delivery_date_min);
return $day_name;
} else {
return $delivery_date_min->format('d M');
}
}
// Range delivery - make it more informative
$min_days_from_now = calculateDaysFromNow($delivery_date_min, $now);
$max_days_from_now = calculateDaysFromNow($delivery_date_max, $now);
// If both dates are within a week, show day names
if ($max_days_from_now <= 7) {
$min_day_name = getDayName($delivery_date_min);
$max_day_name = getDayName($delivery_date_max);
if ($min_days_from_now == 1) {
return "Besok - {$max_day_name}";
} elseif ($min_days_from_now == 2) {
return "Lusa - {$max_day_name}";
} else {
return "{$min_day_name} - {$max_day_name}";
}
} else {
// For longer ranges, use dates
return $delivery_date_min->format('d M') . ' - ' . $delivery_date_max->format('d M');
}
}
// Test function untuk memverifikasi kasus-kasus yang disebutkan
function testCases()
{
echo "<h3>Testing ETD Cases:</h3>";
// Case 1: Andi - Rabu 2 siang, ETD 1-2 hari
$result1 = format_shipping_etd('1-2', 'regular', '2025-08-01 10:20:00');
echo "Case 1 (Andi): " . $result1['formatted_text'] . "<br>";
// Case 2: Anton - Kamis 1 pagi, ETD 1-2 hari
$result2 = format_shipping_etd('1-2', 'regular', '2025-07-31 01:00:00');
echo "Case 2 (Anton): " . $result2['formatted_text'] . "<br>";
// Case 3: Budi - Rabu 5 sore, ETD 1-2 hari
$result3 = format_shipping_etd('1-2', 'regular', '2025-07-30 17:00:00');
echo "Case 3 (Budi): " . $result3['formatted_text'] . "<br>";
// Case 4: Cinta - Rabu 3 sore, instant 1-2 jam
$result4 = format_shipping_etd('1-2 Hours', 'instant', '2025-07-30 15:00:00');
echo "Case 4 (Cinta): " . $result4['formatted_text'] . "<br>";
// Case 5: Ayu - Rabu 5 sore, instant 2-3 jam
$result5 = format_shipping_etd('2-3 Hours', 'instant', '2025-08-01 17:00:00');
echo "Case 5 (Ayu): " . $result5['formatted_text'] . "<br>";
// Case 6: Joko - Jumat 12 siang, instant 2-3 jam (should be next business day)
$result6 = format_shipping_etd('2-3 Hours', 'instant', '2025-08-01 12:00:00');
echo "Case 6 (Joko - Instant): " . $result6['formatted_text'] . "<br>";
// Case 7: Test Next Day service - Jumat sebelum jam 4
$result7 = format_shipping_etd('1', 'next_day', '2025-08-01 15:00:00');
echo "Case 7 (Next Day - Jumat 3 sore): " . $result7['formatted_text'] . "<br>";
// Case 8: Test Next Day service - Jumat setelah jam 4
$result8 = format_shipping_etd('1', 'next_day', '2025-08-01 17:00:00');
echo "Case 8 (Next Day - Jumat 5 sore): " . $result8['formatted_text'] . "<br>";
}
/**
* Get shipping service display name berdasarkan service code
* @param string $service_code - Service code dari RajaOngkir
* @param string $description - Description dari RajaOngkir
* @return string - Display name yang user-friendly
*/
function get_shipping_service_display_name($method_data)
{
// Jika input adalah object dari database (prioritas tertinggi)
if (is_object($method_data)) {
// Prioritas 1: Gunakan field 'name' dari database jika ada dan tidak kosong
if (isset($method_data->name) && !empty(trim($method_data->name))) {
return trim($method_data->name);
}
// Prioritas 2: Gunakan field 'shipper' dari database jika ada dan tidak kosong
if (isset($method_data->shipper) && !empty(trim($method_data->shipper))) {
return trim($method_data->shipper);
}
// Prioritas 3: Gunakan biteship_service_name jika ada
if (isset($method_data->biteship_service_name) && !empty(trim($method_data->biteship_service_name))) {
return trim($method_data->biteship_service_name);
}
// Fallback: Format service_code jika ada
if (isset($method_data->service_code) && !empty(trim($method_data->service_code))) {
return ucwords(str_replace('_', ' ', trim($method_data->service_code)));
}
}
// Legacy support: jika input adalah string (service_code) dan description
if (is_string($method_data)) {
$service_code = $method_data;
$description = func_num_args() > 1 ? func_get_arg(1) : '';
// Static mapping untuk service codes yang umum (sebagai fallback)
$service_names = [
// JNE
'reg' => 'JNE Regular',
'oke' => 'JNE OKE',
'yes' => 'JNE YES',
'ctc' => 'JNE City Courier',
'ctcyes' => 'JNE City Courier Express',
// Gojek
'instant' => 'GoSend Instant',
'same_day' => 'GoSend Same Day',
// Grab
'express' => 'GrabExpress',
// TIKI
'eco' => 'TIKI Economy',
'ons' => 'TIKI Overnight Service',
'sds' => 'TIKI Same Day Service',
];
$service_code_lower = strtolower($service_code);
if (isset($service_names[$service_code_lower])) {
return $service_names[$service_code_lower];
}
// Fallback ke description jika ada
if (!empty($description)) {
return $description;
}
// Final fallback: Format service code
return ucwords(str_replace('_', ' ', $service_code));
}
return 'Unknown Service';
}
function get_province_name($province_id)
{
$ci = &get_instance();
$province_name = $ci->db
->select('province')
->from('indonesia_provinces')
->where('rajaongkir_province_id', $province_id)
->get()
->row()->province;
return $province_name;
}
function get_district_name($district_id)
{
$ci = &get_instance();
$district_name = $ci->db
->select('district')
->from('indonesia_districts')
->where('rajaongkir_id_district', $district_id)
->get()
->row()->district;
return $district_name;
}
function get_subdistrict_name($subdistrict_id)
{
$ci = &get_instance();
$subdistrict_name = $ci->db
->select('subdistrict')
->from('indonesia_subdistricts')
->where('rajaongkir_id_subdistrict', $subdistrict_id)
->get()
->row()->subdistrict;
return $subdistrict_name;
}