⚠️ Ceci est une estimation indicative uniquement. Les autorités douanières, transporteurs et courtiers décident de la classification, des droits, taxes, frais et de l'admissibilité finaux.
`; } async function init(){ const selCountry = $('pp-country-select'); const selOrigin = $('pp-origin-select'); if(selCountry){ selCountry.innerHTML = ''; const sorted = countryList.slice().sort((a,b)=>a[1].localeCompare(b[1])); sorted.forEach(([slug,name])=> selCountry.append(new Option(name, slug))); selCountry.value = countryParam; selCountry.addEventListener('change', e => renderCountry(e.target.value, true)); } if(selOrigin){ selOrigin.innerHTML = ''; selOrigin.append(new Option('Any / MFN', '')); countryList.slice().sort((a,b)=>a[1].localeCompare(b[1])).forEach(([slug,name])=> selOrigin.append(new Option(name, slug))); selOrigin.value = originParam; selOrigin.addEventListener('change', e => renderOrigin(e.target.value, true)); } ['hs_origin','hs_dest'].forEach(id=>{ const el = $(id); if(el) el.addEventListener('input',()=>{el.dataset.touched='1';}); }); try{ DEMINIMIS_MAP = await loadDeminimisSheet(); }catch(e){ DEMINIMIS_MAP = {}; } try{ CUSTOMS_DATA = await loadCustomsFromSheet(); }catch(e){ CUSTOMS_DATA = {countries:{}}; } try{ TARIFF_RULES = await loadTariffsFromSheet(); }catch(e){ TARIFF_RULES = []; } await loadHS(); renderCountry(countryParam, false); renderOrigin(originParam, false); const hsInput = $('pp-hs-search'); if(hsInput) hsInput.addEventListener('input', computeHSRates); } const ddp = $('pp-ddp'); const ddu = $('pp-ddu'); const ddText = $('pp-dd-text'); function setMode(mode){ if(!ddp || !ddu || !ddText) return; if(mode==='ddp'){ ddp.classList.add('pp-btn-blue'); ddu.classList.remove('pp-btn-blue'); ddText.innerHTML = '
DDP : l’expéditeur prépaie les droits/taxes lorsque cela est pris en charge. Cela peut réduire les refus de livraison et les frais surprises pour les destinataires.'; }else{ ddu.classList.add('pp-btn-blue'); ddp.classList.remove('pp-btn-blue'); ddText.innerHTML = '
DAP/DDU : le destinataire paie les droits/taxes à la livraison. Le coût initial est plus faible, mais le risque de retards, de refus ou de contact supplémentaire de la part du transporteur est plus élevé.'; } } if(ddp && ddu){ ddp.addEventListener('click',()=>setMode('ddp')); ddu.addEventListener('click',()=>setMode('ddu')); setMode('ddu'); } const guessBtn = $('hs_guess_btn'); if(guessBtn){ guessBtn.addEventListener('click', async ()=>{ const box = $('hs_keyword'); const q = (box?.value||'').trim(); if(!q){ alert('Saisissez d’abord un mot-clé de marchandise.'); return; } try{ const r = await fetch('https://hts.usitc.gov/api/search?q=' + encodeURIComponent(q)); const j = await r.json(); const first = (j && j.response && j.response.docs && j.response.docs[0]) || null; if(first && first.hscode) $('hs_code').value = String(first.hscode).replace(/\s+/g,''); else alert('Aucune suggestion trouvée. Veuillez saisir le code HS6 manuellement.'); }catch(err){ alert('La recherche par mot-clé n’est pas disponible ici. Veuillez saisir le code HS6 manuellement.'); } }); } const estimateBtn = $('hs_estimate_btn'); if(estimateBtn){ estimateBtn.addEventListener('click', async ()=>{ const origin = ($('hs_origin')?.value||'').toUpperCase().trim(); const dest = ($('hs_dest')?.value||'').toUpperCase().trim(); const hs6 = ($('hs_code')?.value||'').replace(/\D/g,'').slice(0,6); const valStr = $('hs_value')?.value; const wtStr = $('hs_weight')?.value; const basis = $('hs_basis')?.value || 'CIF'; const payer = $('hs_payer')?.value || 'Recipient'; const result = $('hs_result'); if(!origin || !dest){ alert('Saisissez les codes ISO3 d’origine et de destination.'); return; } if(!hs6){ alert('Veuillez saisir un code HS à 6 chiffres ou utiliser Suggérer.'); return; } if(result) result.innerHTML = '
Calcul de l'estimation en cours…
'; const data = await loadAllData(); const t = tariffFor(origin, dest, hs6, data.tariffs); const adval = (t && t.adval!=null) ? Number(t.adval) : null; const specPerKg = parseSpecificPerKg(t && t.specific); const dm = deMinimis(dest, data.dm); const vatPct = vatPercent(dest, data.vat); const declared = Number(valStr||0); const shipping = 0, insurance = 0; const customsValue = (basis === 'CIF') ? (declared + shipping + insurance) : declared; let duty = 0; if(!(declared 0 ? specPerKg * Number(wtStr||0) : 0); let vat = 0; if(!(declared