{"id":1452,"date":"2026-04-11T11:03:42","date_gmt":"2026-04-11T11:03:42","guid":{"rendered":"https:\/\/eze-shuttle.com\/?page_id=1452"},"modified":"2026-05-16T06:44:12","modified_gmt":"2026-05-16T06:44:12","slug":"billet-collectif-historique-admin","status":"publish","type":"page","link":"https:\/\/eze-shuttle.com\/zh\/billet-collectif-historique-admin\/","title":{"rendered":"Billet Collectif Historique Admin"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1452\" class=\"elementor elementor-1452\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-50459e47 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"50459e47\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;shape_divider_bottom&quot;:&quot;triangle&quot;,&quot;shape_divider_bottom_negative&quot;:&quot;yes&quot;}\">\n\t\t\t\t\t\t\t<div class=\"elementor-background-overlay\"><\/div>\n\t\t\t\t\t\t<div class=\"elementor-shape elementor-shape-bottom\" aria-hidden=\"true\" data-negative=\"true\">\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 1000 100\" preserveAspectRatio=\"none\">\n\t<path class=\"elementor-shape-fill\" d=\"M500.2,94.7L0,0v100h1000V0L500.2,94.7z\"\/>\n<\/svg>\t\t<\/div>\n\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-4b61b66f\" data-id=\"4b61b66f\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-3f2ee07d elementor-icon-list--layout-inline elementor-align-center elementor-widget__width-auto elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list\" data-id=\"3f2ee07d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"icon-list.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<ul class=\"elementor-icon-list-items elementor-inline-items\">\n\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\">\n\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">Home<\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item elementor-inline-item\">\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"#\">\n\n\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fas-angle-right\" viewBox=\"0 0 256 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\"><\/span>\n\t\t\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-30465e74 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"30465e74\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-2ea7a28c\" data-id=\"2ea7a28c\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-inner-section elementor-element elementor-element-66d36ac9 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"66d36ac9\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-7ac57615\" data-id=\"7ac57615\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<div class=\"elementor-element elementor-element-7ff4b840 elementor-widget elementor-widget-shortcode\" data-id=\"7ff4b840\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <script>\n    window.histoCollectifSlots = {\"COLETTE_VILLAGE_PARKING\":[{\"heure\":\"09h00\",\"places\":3},{\"heure\":\"09h20\",\"places\":3},{\"heure\":\"09H40\",\"places\":3},{\"heure\":\"18H30\",\"places\":3},{\"heure\":\"10H20\",\"places\":3},{\"heure\":\"22h00\",\"places\":3},{\"heure\":\"10H00\",\"places\":3},{\"heure\":\"10H40\",\"places\":3}],\"FRAGONARD_FACTORY\":[{\"heure\":\"09h10\",\"places\":3},{\"heure\":\"09H30\",\"places\":3},{\"heure\":\"09H50\",\"places\":3},{\"heure\":\"18H00\",\"places\":3},{\"heure\":\"10H10\",\"places\":3}]};\n\n    if (!localStorage.getItem('chauffeur_access_histo')) {\n        document.write(`\n            <div style=\"max-width:420px;margin:3rem auto;text-align:center;padding:2rem;border:1px solid #e5e7eb;border-radius:16px;background:#fff;box-shadow:0 10px 30px rgba(0,0,0,0.06);\">\n                <h2 style=\"margin-bottom:1rem;\">\ud83d\udd10 Chauffeur \u2013 Navette Historique<\/h2>\n                <form id=\"pin-form-histo\">\n                    <input type=\"password\" id=\"chauffeur_pin_histo\" placeholder=\"Code chauffeur\" required style=\"width:100%;padding:12px 14px;border:1px solid #d1d5db;border-radius:10px;margin-bottom:1rem;\" \/>\n                    <button type=\"submit\" style=\"width:100%;padding:12px 14px;border:none;border-radius:10px;background:#f28c28;color:#fff;font-weight:600;cursor:pointer;\">Valider<\/button>\n                    <p id=\"pin-error-histo\" style=\"color:red;display:none;margin-top:0.75rem;\">Code incorrect<\/p>\n                <\/form>\n            <\/div>\n        `);\n\n        document.addEventListener('DOMContentLoaded', () => {\n            const form = document.getElementById('pin-form-histo');\n            if (!form) return;\n\n            form.addEventListener('submit', function (e) {\n                e.preventDefault();\n                if (document.getElementById('chauffeur_pin_histo').value === 'ZEZE2025Sachale') {\n                    localStorage.setItem('chauffeur_access_histo', 'true');\n                    location.reload();\n                } else {\n                    document.getElementById('pin-error-histo').style.display = 'block';\n                }\n            });\n        });\n    }\n    <\/script>\n\n    <style>\n        #chauffeur-interface-histo-wrap {\n            display: none;\n            max-width: 1280px;\n            margin: 2.5rem auto;\n            padding: 0 1rem;\n            font-family: sans-serif;\n        }\n\n        .chauffeur-histo-grid {\n            display: grid;\n            grid-template-columns: 1fr 1fr;\n            gap: 2rem;\n            align-items: start;\n        }\n\n        .chauffeur-histo-card {\n            background: #fff;\n            border: 1px solid #e5e7eb;\n            border-radius: 18px;\n            padding: 2rem;\n            box-shadow: 0 12px 30px rgba(0,0,0,0.06);\n        }\n\n        .chauffeur-histo-card h2 {\n            font-size: 2rem;\n            line-height: 1.1;\n            margin: 0 0 1.5rem 0;\n            color: #18223b;\n        }\n\n        .chauffeur-histo-field {\n            margin-bottom: 1.2rem;\n        }\n\n        .chauffeur-histo-field label {\n            display: block;\n            margin-bottom: 0.5rem;\n            color: #667085;\n            font-weight: 500;\n        }\n\n        .chauffeur-histo-field input,\n        .chauffeur-histo-field select {\n            width: 100%;\n            max-width: 100%;\n            padding: 12px 14px;\n            border: 1px solid #d0d5dd;\n            border-radius: 10px;\n            background: #fff;\n            box-sizing: border-box;\n        }\n\n        .chauffeur-histo-actions {\n            margin-top: 1.25rem;\n        }\n\n        .chauffeur-histo-btn {\n            display: inline-block;\n            width: 100%;\n            padding: 13px 16px;\n            border: none;\n            border-radius: 10px;\n            cursor: pointer;\n            font-weight: 700;\n            font-size: 1rem;\n            transition: 0.2s ease;\n        }\n\n        .chauffeur-histo-btn:hover {\n            opacity: 0.92;\n            transform: translateY(-1px);\n        }\n\n        .chauffeur-histo-btn-primary {\n            background: #f28c28;\n            color: #fff;\n        }\n\n        .chauffeur-histo-btn-secondary {\n            background: #18223b;\n            color: #fff;\n        }\n\n        .chauffeur-histo-help {\n            margin-top: 0.75rem;\n            color: #667085;\n            font-size: 0.92rem;\n        }\n\n        @media (max-width: 950px) {\n            .chauffeur-histo-grid {\n                grid-template-columns: 1fr;\n            }\n\n            .chauffeur-histo-card h2 {\n                font-size: 1.8rem;\n            }\n        }\n    <\/style>\n\n    <div id=\"chauffeur-interface-histo-wrap\">\n        <div class=\"chauffeur-histo-grid\">\n\n            <div class=\"chauffeur-histo-card\">\n                <h2>\ud83d\udcc4 G\u00e9n\u00e9rer un billet collectif \u2013 Navette M\u00e9hari<\/h2>\n\n                <form id=\"form-billet-histo\">\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"depart_histo\">\ud83d\udea9 Lieu de d\u00e9part :<\/label>\n                        <select name=\"depart\" id=\"depart_histo\" required>\n                            <option value=\"\">-- Choisissez --<\/option>\n                            <option value=\"FRAGONARD_FACTORY\">Fragonard (Usine, bas)<\/option>\n                            <option value=\"COLETTE_VILLAGE_PARKING\">Parking Colette (milieu)<\/option>\n                        <\/select>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"arrivee_histo\">\ud83c\udfaf Destination :<\/label>\n                        <select name=\"arrivee\" id=\"arrivee_histo\" required>\n                            <option value=\"\">-- Choisissez --<\/option>\n                            <option value=\"FRAGONARD_FACTORY\">Fragonard (Usine, bas)<\/option>\n                            <option value=\"COLETTE_VILLAGE_PARKING\">Parking Colette (milieu)<\/option>\n                        <\/select>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"date_histo\">\ud83d\udcc5 Date :<\/label>\n                        <input type=\"date\" name=\"date\" id=\"date_histo\" required>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"heure_histo\">\ud83d\udd52 Horaire :<\/label>\n                        <select name=\"heure\" id=\"heure_histo\" required>\n                            <option value=\"\">Choisissez d\u00e9part, destination et une date<\/option>\n                        <\/select>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"chauffeur_histo\">\ud83d\ude97 Nom du chauffeur :<\/label>\n                        <input type=\"text\" name=\"chauffeur\" id=\"chauffeur_histo\" required>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-actions\">\n                        <button type=\"submit\" class=\"chauffeur-histo-btn chauffeur-histo-btn-primary\">\ud83d\udda8 G\u00e9n\u00e9rer le billet<\/button>\n                    <\/div>\n                <\/form>\n            <\/div>\n\n            <div class=\"chauffeur-histo-card\">\n                <h2>\ud83d\udcca G\u00e9n\u00e9rer un rapport journalier \u2013 Navette M\u00e9hari<\/h2>\n\n                <form id=\"form-rapport-histo\">\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"chauffeur_rapport_histo\">\ud83d\ude97 Nom du chauffeur :<\/label>\n                        <input type=\"text\" name=\"chauffeur_rapport_histo\" id=\"chauffeur_rapport_histo\" required>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"date_debut_histo\">\ud83d\udcc5 Date de d\u00e9but :<\/label>\n                        <input type=\"date\" name=\"date_debut_histo\" id=\"date_debut_histo\" required>\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-field\">\n                        <label for=\"date_fin_histo\">\ud83d\udcc5 Date de fin (facultative) :<\/label>\n                        <input type=\"date\" name=\"date_fin_histo\" id=\"date_fin_histo\">\n                    <\/div>\n\n                    <div class=\"chauffeur-histo-actions\">\n                        <button type=\"submit\" class=\"chauffeur-histo-btn chauffeur-histo-btn-secondary\">\ud83d\udcc8 G\u00e9n\u00e9rer le rapport journalier<\/button>\n                    <\/div>\n\n                    <p class=\"chauffeur-histo-help\">\n                        Laisse la date de fin vide pour g\u00e9n\u00e9rer le rapport d\u2019une seule journ\u00e9e.\n                    <\/p>\n                <\/form>\n            <\/div>\n\n        <\/div>\n    <\/div>\n\n    <script>\n    if (localStorage.getItem('chauffeur_access_histo') === 'true') {\n        const iface = document.getElementById('chauffeur-interface-histo-wrap');\n        if (iface) iface.style.display = 'block';\n    }\n\n    document.addEventListener('DOMContentLoaded', function () {\n        const departSel   = document.getElementById('depart_histo');\n        const arriveeSel  = document.getElementById('arrivee_histo');\n        const dateInput   = document.getElementById('date_histo');\n        const heureSelect = document.getElementById('heure_histo');\n        const formBillet  = document.getElementById('form-billet-histo');\n        const formRapport = document.getElementById('form-rapport-histo');\n\n        if (!departSel || !arriveeSel || !dateInput || !heureSelect || !formBillet || !formRapport) {\n            return;\n        }\n\n        const ajaxUrl = \"\/wp-admin\/admin-ajax.php\";\n        const slotsByDepart = window.histoCollectifSlots || {};\n\n        function sortSlots(slots) {\n            return [...slots].sort((a, b) => {\n                const toMinutes = (heure) => {\n                    const m = (heure || '').match(\/^(\\d{1,2})h(\\d{1,2})$\/i);\n                    if (!m) return 99999;\n                    return parseInt(m[1], 10) * 60 + parseInt(m[2], 10);\n                };\n\n                return toMinutes(a.heure) - toMinutes(b.heure);\n            });\n        }\n\n        function syncArriveeOptions() {\n            const depVal = departSel.value;\n\n            arriveeSel.querySelectorAll('option').forEach(opt => {\n                if (!opt.value) return;\n                opt.disabled = (opt.value === depVal);\n            });\n\n            if (arriveeSel.value === depVal) {\n                arriveeSel.value = '';\n            }\n        }\n\n        function updateHoraires() {\n            const dep  = departSel.value;\n            const arr  = arriveeSel.value;\n            const date = dateInput.value;\n\n            heureSelect.innerHTML = '<option value=\"\">Chargement...<\/option>';\n\n            if (!dep || !arr || !date) {\n                heureSelect.innerHTML = '<option value=\"\">Choisissez d\u00e9part, destination et une date<\/option>';\n                return;\n            }\n\n            const slots = Array.isArray(slotsByDepart[dep]) ? sortSlots(slotsByDepart[dep]) : [];\n\n            if (!slots.length) {\n                heureSelect.innerHTML = '<option value=\"\">Aucun horaire configur\u00e9 pour ce point de d\u00e9part<\/option>';\n                return;\n            }\n\n            const promises = slots.map(slot => {\n                const heure = slot.heure;\n                const urlRem = `${ajaxUrl}?action=get_histo_remaining&date=${encodeURIComponent(date)}&heure=${encodeURIComponent(heure)}&depart=${encodeURIComponent(dep)}&arrivee=${encodeURIComponent(arr)}`;\n\n                return fetch(urlRem)\n                    .then(r => r.json())\n                    .then(res => ({\n                        heure,\n                        left: res && res.data && typeof res.data.remaining !== 'undefined'\n                            ? parseInt(res.data.remaining, 10)\n                            : 0\n                    }))\n                    .catch(() => ({\n                        heure,\n                        left: 0\n                    }));\n            });\n\n            Promise.all(promises).then(results => {\n                heureSelect.innerHTML = '';\n\n                let count = 0;\n\n                results.forEach(r => {\n                    const opt = document.createElement('option');\n                    const full = r.left <= 0;\n\n                    opt.value = full ? '' : r.heure;\n                    opt.disabled = full;\n\n                    opt.textContent = full\n                        ? `${r.heure} (complet)`\n                        : `${r.heure} (${r.left} place${r.left > 1 ? 's' : ''} restante${r.left > 1 ? 's' : ''})`;\n\n                    if (!full) count++;\n\n                    heureSelect.appendChild(opt);\n                });\n\n                if (count === 0) {\n                    heureSelect.innerHTML = '<option value=\"\">Aucun horaire disponible pour ce point de d\u00e9part<\/option>';\n                }\n            });\n        }\n\n        departSel.addEventListener('change', () => {\n            syncArriveeOptions();\n            updateHoraires();\n        });\n\n        arriveeSel.addEventListener('change', updateHoraires);\n        dateInput.addEventListener('change', updateHoraires);\n\n        formBillet.addEventListener('submit', function (e) {\n            e.preventDefault();\n\n            const dep       = departSel.value;\n            const arr       = arriveeSel.value;\n            const date      = dateInput.value;\n            const heure     = heureSelect.value;\n            const chauffeur = document.getElementById('chauffeur_histo').value;\n\n            if (!dep || !arr || !date || !heure || !chauffeur) {\n                alert(\"Veuillez remplir tous les champs du billet collectif.\");\n                return;\n            }\n\n            const url = `\/wp-content\/themes\/hello-elementor\/generer-billet-histo.php?depart=${encodeURIComponent(dep)}&arrivee=${encodeURIComponent(arr)}&date=${encodeURIComponent(date)}&heure=${encodeURIComponent(heure)}&chauffeur=${encodeURIComponent(chauffeur)}`;\n            window.open(url, '_blank');\n        });\n\n        formRapport.addEventListener('submit', function (e) {\n            e.preventDefault();\n\n            const chauffeur = document.getElementById('chauffeur_rapport_histo').value.trim();\n            const dateDebut = document.getElementById('date_debut_histo').value;\n            let dateFin = document.getElementById('date_fin_histo').value;\n\n            if (!chauffeur || !dateDebut) {\n                alert(\"Veuillez remplir le chauffeur et la date de d\u00e9but du rapport.\");\n                return;\n            }\n\n            if (!dateFin) {\n                dateFin = dateDebut;\n            }\n\n            if (dateFin < dateDebut) {\n                alert(\"La date de fin ne peut pas \u00eatre ant\u00e9rieure \u00e0 la date de d\u00e9but.\");\n                return;\n            }\n\n            const url = `\/wp-content\/themes\/hello-elementor\/generer-rapport-journalier-histo.php?chauffeur=${encodeURIComponent(chauffeur)}&date_debut=${encodeURIComponent(dateDebut)}&date_fin=${encodeURIComponent(dateFin)}`;\n            window.open(url, '_blank');\n        });\n\n        syncArriveeOptions();\n    });\n    <\/script>\n    <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\u5bb6<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1452","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/pages\/1452","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/comments?post=1452"}],"version-history":[{"count":10,"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/pages\/1452\/revisions"}],"predecessor-version":[{"id":1579,"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/pages\/1452\/revisions\/1579"}],"wp:attachment":[{"href":"https:\/\/eze-shuttle.com\/zh\/wp-json\/wp\/v2\/media?parent=1452"}],"curies":[{"name":"\u53ef\u6e7f\u6027\u7c89\u5242","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}