/** * --- Pengiriman Toko Helpers --- */ /** * Fetch and cache East Java kabupaten/cities from Biteship API * Returns array of [kabupaten_id, kabupaten_name, province_name, is_allowed] */ function fetchAndCachePengirimanTokoRegions() { $apiUrl = 'https://api.biteship.com/v1/maps/areas/countries/ID'; $apiKey = getSetting('biteship_api_key'); if (!$apiKey) return false; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $apiKey ]); $result = curl_exec($ch); curl_close($ch); $data = json_decode($result, true); if (!$data || !isset($data['areas'])) return false; $pdo = db(); $now = date('Y-m-d H:i:s'); foreach ($data['areas'] as $area) { if (strtolower($area['province']) === 'jawa timur') { // Upsert region $stmt = $pdo->prepare("REPLACE INTO pengiriman_toko_regions (kabupaten_id, kabupaten_name, province_name, is_allowed, last_updated) VALUES (?, ?, ?, 1, ?)"); $stmt->execute([ $area['id'], $area['name'], $area['province'], $now ]); } } return true; } /** * Get allowed kabupaten/cities for Pengiriman Toko * Returns array of [kabupaten_id, kabupaten_name] */ function getAllowedPengirimanTokoRegions() { $stmt = db()->prepare("SELECT kabupaten_id, kabupaten_name FROM pengiriman_toko_regions WHERE is_allowed = 1"); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } /** * Calculate road route distance (km) using OpenRouteService API * Returns float distance in km, or false on failure */ function getRoadRouteDistance($fromLat, $fromLng, $toLat, $toLng) { $apiKey = getSetting('openrouteservice_api_key'); if (!$apiKey) return false; $url = 'https://api.openrouteservice.org/v2/directions/driving-car?api_key=' . urlencode($apiKey) . '&start=' . $fromLng . ',' . $fromLat . '&end=' . $toLng . ',' . $toLat; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); $data = json_decode($result, true); if (isset($data['features'][0]['properties']['segments'][0]['distance'])) { // distance in meters return round($data['features'][0]['properties']['segments'][0]['distance'] / 1000, 2); } return false; } /** * Haversine formula (distance in km) */ function haversineDistance($lat1, $lon1, $lat2, $lon2) { $earthRadius = 6371; // km $dLat = deg2rad($lat2 - $lat1); $dLon = deg2rad($lon2 - $lon1); $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return $earthRadius * $c; } /** * Get Pengiriman Toko distance (tries road route, falls back to Haversine + margin) * Returns [distance_km, method] where method is 'api' or 'fallback' */ function getPengirimanTokoDistance($toLat, $toLng) { $fromLat = defined('PENGIRIMAN_TOKO_STORE_LAT') ? PENGIRIMAN_TOKO_STORE_LAT : -7.257472; $fromLng = defined('PENGIRIMAN_TOKO_STORE_LNG') ? PENGIRIMAN_TOKO_STORE_LNG : 112.752088; $distance = getRoadRouteDistance($fromLat, $fromLng, $toLat, $toLng); if ($distance !== false) { return [$distance, 'api']; } // Fallback: Haversine + margin $haversine = haversineDistance($fromLat, $fromLng, $toLat, $toLng); $margin = defined('PENGIRIMAN_TOKO_FALLBACK_MARGIN_PERCENT') ? PENGIRIMAN_TOKO_FALLBACK_MARGIN_PERCENT : 10; $distanceWithMargin = round($haversine * (1 + $margin/100), 2); return [$distanceWithMargin, 'fallback']; } /** * Calculate Pengiriman Toko shipping option for current cart and address * @param float $toLat Customer latitude * @param float $toLng Customer longitude * @param string $kabupatenId Customer kabupaten/city ID * @return array|null [price, estimated_days, distance_km, method, label] or null if not eligible */ function getPengirimanTokoShipping($toLat, $toLng, $kabupatenId) { // 1. Check if region is allowed $allowedRegions = getAllowedPengirimanTokoRegions(); $allowedIds = array_column($allowedRegions, 'kabupaten_id'); if (!in_array($kabupatenId, $allowedIds)) return null; // 2. Check if all cart items are in allowed categories $cart = getCart(); if (!$cart) return null; $ruleStmt = db()->prepare("SELECT allowed_categories FROM pengiriman_toko_rules WHERE enabled = 1 LIMIT 1"); $ruleStmt->execute(); $rule = $ruleStmt->fetch(); if (!$rule) return null; $allowedCatIds = array_map('trim', explode(',', $rule['allowed_categories'])); foreach ($cart as $item) { if (!in_array($item['category_id'], $allowedCatIds)) return null; } // 3. Calculate distance list($distance, $method) = getPengirimanTokoDistance($toLat, $toLng); // 4. Find matching price/days range $stmt = db()->prepare("SELECT * FROM pengiriman_toko_rules WHERE enabled = 1 AND min_distance_km <= :d AND max_distance_km >= :d ORDER BY min_distance_km ASC LIMIT 1"); $stmt->execute(['d' => $distance]); $range = $stmt->fetch(); if (!$range) return null; return [ 'price' => (int)$range['price'], 'estimated_days' => (int)$range['estimated_days'], 'distance_km' => $distance, 'method' => $method, 'label' => 'Pengiriman Toko (' . $distance . ' km, ' . $range['estimated_days'] . ' hari)' ]; }
Warning: Cannot modify header information - headers already sent by (output started at /home/bagohome/preview.shop.bagohomedecor.id/shop.bagohomedecor.id/includes/cart.php:1) in /home/bagohome/preview.shop.bagohomedecor.id/shop.bagohomedecor.id/includes/Router.php on line 68
404 Not Found

404 Not Found

The requested URL was not found on this server.