⚠️ Esto es solo una estimación orientativa. Las autoridades aduaneras, los transportistas y los agentes de aduanas determinan la clasificación final, los aranceles, los impuestos, las tasas y la admisibilidad.
`; } 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('Cualquiera / NMF', '')); 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: el remitente paga por adelantado los aranceles/impuestos cuando es posible. Esto puede reducir las negativas de entrega y los cargos sorpresa para los destinatarios.'; }else{ ddu.classList.add('pp-btn-blue'); ddp.classList.remove('pp-btn-blue'); ddText.innerHTML = '
DAP/DDU: el destinatario paga los aranceles/impuestos en la entrega. El coste inicial es menor, pero hay más riesgo de retrasos, rechazos o contacto adicional por parte del transportista.'; } } 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('Introduce primero una palabra clave del producto.'); 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('No se encontró ninguna sugerencia. Introduce el código HS6 manualmente.'); }catch(err){ alert('La búsqueda por palabra clave no está disponible aquí. Introduce el código HS6 manualmente.'); } }); } 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('Introduce el país de origen y de destino en formato ISO3.'); return; } if(!hs6){ alert('Introduce un código HS de 6 dígitos o usa Sugerir.'); return; } if(result) result.innerHTML = '
Calculando estimación…
'; 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