/** * 123VTC — vtc-distance.js * ───────────────────────────────────────────────────────────────────────────── * Calcule automatiquement la distance (km) entre le point de départ et * l'arrivée via l'API Google Maps, puis estime le prix selon la grille * tarifaire. Met à jour le champ caché `distance_km` avant la soumission. * * INSTALLATION * ──────────── * 1. Charger le script dans functions.php : * * add_action('wp_enqueue_scripts', function () { * // Remplacez YOUR_GOOGLE_MAPS_API_KEY par votre clé * wp_enqueue_script( * 'google-maps', * 'https://maps.googleapis.com/maps/api/js' * . '?key=YOUR_GOOGLE_MAPS_API_KEY' * . '&libraries=places' * . '&callback=vtcInitMaps', * [], * null, * true // chargé dans le footer * ); * wp_enqueue_script( * 'vtc-distance', * get_template_directory_uri() . '/js/vtc-distance.js', * ['google-maps'], * '1.0.0', * true * ); * }); * * 2. Ajouter ces champs dans votre formulaire HTML : * * * * * * * * *
* * ───────────────────────────────────────────────────────────────────────────── */ /* ─── Grille tarifaire (doit correspondre à functions.php) ─────────────────── */ var VTC_RATES = { matin: 1.80, // 06h–10h journee: 1.50, // 10h–16h soir: 1.80, // 16h–22h nuit: 1.90, // 22h–06h special: 1.90, // Dimanche & jours fériés minimum: 20.00 }; /* ─── Jours fériés français ───────────────────────────────────────────────── Recalculés côté JS pour l'aperçu uniquement. Le calcul officiel (et binding) reste dans functions.php côté serveur. */ function vtcGetEaster(year) { var a = year % 19, b = Math.floor(year / 100), c = year % 100; var d = Math.floor(b / 4), e = b % 4, f = Math.floor((b + 8) / 25); var g = Math.floor((b - f + 1) / 3); var h = (19 * a + b - d - g + 15) % 30; var i = Math.floor(c / 4), k = c % 4; var l = (32 + 2 * e + 2 * i - h - k) % 7; var m = Math.floor((a + 11 * h + 22 * l) / 451); var month = Math.floor((h + l - 7 * m + 114) / 31) - 1; // 0-based var day = ((h + l - 7 * m + 114) % 31) + 1; return new Date(year, month, day); } function vtcIsPublicHoliday(date) { var y = date.getFullYear(); var easter = vtcGetEaster(y); var d = function (m, day) { return new Date(y, m - 1, day); }; var add = function (base, days) { var r = new Date(base); r.setDate(r.getDate() + days); return r; }; var fmt = function (dt) { return dt.getFullYear() + '-' + String(dt.getMonth() + 1).padStart(2, '0') + '-' + String(dt.getDate()).padStart(2, '0'); }; var target = fmt(date); var holidays = [ d(1,1), add(easter,1), d(5,1), d(5,8), add(easter,39), add(easter,49), d(7,14), d(8,15), d(11,1), d(11,11), d(12,25) ]; return holidays.some(function (h) { return fmt(h) === target; }); } /* ─── Calcul du tarif ────────────────────────────────────────────────────── */ function vtcGetRate(dateStr, timeStr) { if (!dateStr || !timeStr) return null; var date = new Date(dateStr); var hour = parseInt(timeStr.split(':')[0], 10); var isSun = date.getDay() === 0; var isFer = vtcIsPublicHoliday(date); if (isSun || isFer) return { rate: VTC_RATES.special, label: isSun ? 'Dimanche' : 'Jour férié' }; if (hour >= 6 && hour < 10) return { rate: VTC_RATES.matin, label: 'Matin (6h–10h)' }; if (hour >= 10 && hour < 16) return { rate: VTC_RATES.journee, label: 'Journée (10h–16h)' }; if (hour >= 16 && hour < 22) return { rate: VTC_RATES.soir, label: 'Soir (16h–22h)' }; return { rate: VTC_RATES.nuit, label: 'Nuit (22h–6h)' }; } function vtcCalculatePrice(distanceKm, dateStr, timeStr) { var info = vtcGetRate(dateStr, timeStr); if (!info) return null; var price = Math.round(distanceKm * info.rate * 100) / 100; return { price: Math.max(VTC_RATES.minimum, price), rate: info.rate, label: info.label, isMinimum: price < VTC_RATES.minimum }; } /* ─── Mise à jour de l'aperçu du prix ────────────────────────────────────── */ function vtcUpdatePreview(distanceKm) { var preview = document.getElementById('vtc_price_preview'); if (!preview) return; var dateStr = (document.getElementById('vtc_date') || {}).value || ''; var timeStr = (document.getElementById('vtc_time') || {}).value || ''; var result = vtcCalculatePrice(distanceKm, dateStr, timeStr); if (!result) { preview.innerHTML = ''; return; } var priceStr = result.price.toFixed(2).replace('.', ',') + '\u00a0€'; var minNote = result.isMinimum ? '(tarif minimum appliqué)' : '' + distanceKm.toFixed(1).replace('.', ',') + '\u00a0km × ' + result.rate.toFixed(2).replace('.', ',') + '\u00a0€/km'; preview.innerHTML = '