Centro de análisis
de costos & Pricing

Estrategia de pricing para posicionamiento web

¿Cómo funciona esta calculadora? Ingresa los datos de tu producto en los bloques correspondientes y el sistema calculará automáticamente el PVP BRUTO ML (precio de venta al público en el marketplace), verificando que el margen objetivo quede garantizado después de descontar todos los fees de la plataforma. La fórmula base es: PVP BRUTO ML = ($ A Recibir + Cargo Fijo + Envío) ÷ (1 − Comisión%) donde $ A Recibir = PV NETO ML × (1 + IVA%) y PV NETO ML = Costo Neto ÷ (1 − Margen%).
01Parámetros base — ingresa costo neto, PVP publicado e IVA
02Margen objetivo — selecciona el % de ganancia sobre ventas
03Marketplace — elige la plataforma y configura sus fees
04Construcción — revisa el PVP BRUTO ML calculado
05Pricing Test — testea cualquier precio para ver su margen real
06Competencia — añade competidores y analiza el mercado
Parámetros baseiVariables de entrada del modeloDefine el costo de tu producto y el precio que cobras hoy. Estos valores son la base de toda la cadena de cálculo: sin un costo neto correcto, el PVP resultante será inválido.PV NETO = Costo ÷ (1 − Margen%)
CLP
CLP
%
Costo neto $0
Costo + IVA $0
Margen objetivo sobre ventasiGross Margin % (margen bruto sobre ventas)Porcentaje de ganancia calculado sobre el precio de venta neto (PV NETO ML), no sobre el costo. Diferente al markup: un margen del 30% significa que la ganancia representa el 30% del precio que recibes, equivalente a un markup del 42.8% sobre costo.Margen = (PV NETO − Costo) ÷ PV NETO × 100
Ajuste fino 0%
Selecciona el marketplaceiConfiguración de fees por canalCada marketplace tiene su propia estructura de fees: comisión variable sobre PVP, cargo fijo por transacción y costo logístico. Estos tres componentes determinan cuánto descuenta la plataforma de tu precio publicado antes de liquidarte.$ A Recibir = PVP − (PVP × com%) − fijo − envío
Mercado Libre
Comisión ref.: 0%
Falabella
Comisión ref.: 0%
Walmart
Comisión ref.: 0%
Paris
Comisión ref.: 0%
BICE Store
Comisión ref.: 0%
Pricing TestiSimulador de escenarios de precioPermite ingresar cualquier PVP y calcular en tiempo real los fees descontados, el $ A Recibir neto, y los tres tipos de margen: sobre ventas (gross margin), sobre costo (markup) y sobre costo+IVA. Úsalo para validar precios de competidores o testar descuentos.Margen s/ventas = (PV NETO − Costo) ÷ PV NETO
$
Comisión ML
Cargo fijo
Envío
Total fees
$ A recibir
Costo neto
Ganancia $
Margen s/ventas
Margen s/costo
Margen s/costo+IVA
Distribución del PVP $0
Costo
Ganancia
Fees ML
📊 Análisis de competenciaiBenchmark competitivo de precioRegistra el PVP publicado de tus competidores directos. El sistema calcula la diferencia entre su precio y tu PVP óptimo ML, identifica el precio mínimo del mercado y genera un gráfico de posicionamiento. El punto de equilibrio comercial está donde tu precio es competitivo sin sacrificar margen.Δ precio = PVP competidor − PVP óptimo ML
URL / Referencia Nombre PVP publicado
vs. mi PVP
PVP mínimo competencia
PVP máximo competencia
PVP promedio competencia
Mi PVP óptimo ML
Punto de equilibrio — posicionamiento de precio
Agrega competidores para ver el gráfico
Construcción del precio óptimoiPrice Build-Up ModelMetodología de construcción de precio "de adentro hacia afuera": parte del costo, agrega el margen, aplica IVA y ajusta para absorber los fees del marketplace. Garantiza que el margen objetivo se preserve después de todos los descuentos.PVP BRUTO ML = ($ A Recibir + fijo + envío) ÷ (1 − com%) Mercado Libre · 0% margen s/ventas
Costo NETO
$0
base de cálculo
÷
(1 − 0%)
PVP NETO
$0
sin IVA
IVA 0%
$0
impuesto
$ A Recibir
$0
lo que recibes de ML
Costo neto del producto$0
÷ (1 − 0%) — margen sobre ventas÷ 1,00
= PVP NETO (ganancia incluida)$0
Ganancia contenida en PVP NETO$0
+ IVA (0%)$0
= $ A Recibir — PV NETO ML × (1+IVA%) — lo que recibes antes de fees$0
Fees del marketplace: Mercado Libre
− Comisión (0% aplicado sobre el PVP publicado) $0
− Cargo fijo por venta $0
− Costo de envío $0
Total fees marketplace $0
PVP a publicar en ML $0
vs. PVP publicado del producto ($0)
Escenarios de envíoiAnálisis de sensibilidad logísticaSimula 4 rangos de peso/dimensiones para cuantificar el impacto del costo logístico en el PVP BRUTO ML óptimo. El envío es la variable con mayor sensibilidad: reducirlo puede hacer tu precio competitivo sin tocar el margen.PVP óptimo_i = ($ A Recibir + fijo + envío_i) ÷ (1 − com%)

Fórmula: PVP NETO = Costo ÷ (1−margen%) · PVP BRUTO = PVP NETO × (1+IVA%) · PVP ML = (PVP NETO + cargo fijo + envío) ÷ (1−comisión%) · Cargo fijo estimado desde planilla: $3.150 − 12%×$18.990 = $871

🕐 Historial de análisisiRegistro de escenarios de pricingGuarda instantáneas completas del estado del análisis (todos los parámetros, marketplace activo, competidores y margen objetivo). Permite comparar distintos escenarios de pricing y restaurar cualquier configuración anterior en un clic. Los datos persisten en localStorage del navegador.Máx. 20 entradas · localStorage del navegador
Sin análisis guardados. Usa el botón para guardar el estado actual.

El historial se guarda en tu navegador (localStorage). Máximo 20 entradas. Se mantiene al cerrar y reabrir el archivo.

⬇ Exportar análisisiGeneración de reportesExporta el análisis completo en dos formatos: HTML (interactivo, sin conexión) o PDF multipágina con un módulo por página, textos descriptivos de resultados y logo Volcano. El PDF se genera íntegramente en el navegador vía jsPDF, sin necesidad de servidor.PDF: 3 páginas · Parámetros · Construcción · Competencia
🌐
Reporte HTML
Archivo interactivo con todos los resultados del análisis actual. Ábrelo en cualquier navegador sin conexión.
Parámetros base Construcción de precio Pricing Test Competidores Escenarios de envío
📄
Reporte PDF
Documento profesional multipágina — un módulo por página, con texto descriptivo de cada resultado. Ideal para compartir o archivar.
Portada Parámetros Precio óptimo Pricing Test Competidores Escenarios
`; const blob = new Blob([html], {type:'text/html'}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `reporte-ml-${new Date().toISOString().slice(0,10)}.html`; a.click(); st.textContent = '✓ Descargado correctamente'; st.className = 'export-status ok'; setTimeout(()=>{st.textContent='';st.className='export-status';},4000); } catch(e) { st.textContent = '✗ Error: ' + e.message; st.className = 'export-status err'; } } // ─── PDF EXPORT ───────────────────────────────────────────────────────────── async function exportPDF() { const btn = document.querySelector('.pdf-btn'); const st = document.getElementById('pdf-status'); btn.disabled = true; st.textContent = 'Cargando librería...'; st.className = 'export-status busy'; async function loadJsPDF() { if (window.jspdf && window.jspdf.jsPDF) return true; for (const url of [ 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js', 'https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js', ]) { try { await new Promise((res,rej)=>{ const s=document.createElement('script'); s.src=url; s.onload=res; s.onerror=rej; document.head.appendChild(s); }); if (window.jspdf && window.jspdf.jsPDF) return true; } catch(e) {} } return false; } if (!await loadJsPDF()) { st.textContent = '✗ No se pudo cargar jsPDF. Verifica tu conexión.'; st.className = 'export-status err'; btn.disabled = false; return; } st.textContent = 'Generando PDF...'; try { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation:'portrait', unit:'mm', format:'a4' }); const s = getState(); const now = new Date().toLocaleString('es-CL'); const W=210, H=297, ML=14, MR=196, CW=182; // ── Palette ── const BG=[12,12,12], BG2=[22,22,22], SURF=[32,32,32], SURF2=[42,42,42]; const WHT=[245,245,245], MUT=[150,150,150], MUT2=[100,100,100]; const ACC=[220,220,220]; const POS=[80,160,80], NEG=[180,60,60], WRN=[160,120,40]; const POS_BG=[20,45,20], NEG_BG=[50,15,15], WRN_BG=[50,38,10]; const POS_BD=[50,130,50], NEG_BD=[150,50,50], WRN_BD=[140,100,20]; const LOGO_B64 = "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N79Jy/J+73vfw23btgnHS5HHIJFzRXvnB7O5Wn4HvZPqU4Ys/cvKyvBHP/pRu+ozPVy+fcXNN9+Mv/zlL2HixImAiJCRkWEaDjL8lT9b/MpnLYWqQ0QoLCyE5cuXw2uvvZZWZSOGDx+OCxYsgPnz58OVV14pQnECgPAf7nK5QNd1UBQFOnXqlJD34le+ucOSL2AAEEFUyOe2qqpQWloKb775JqxZswY+/fTTtKjHUaNG4aBBg2D06NFwww03QN++fcHj8QiXteQTnfoFfuU+1k6AHjOobY4dOwbXXnttwuti5syZOGjQILjxxhvh29/+NuTk5IjyyOEX20rYgmtZVVUhMzMTXC4XBINBqK6uhjvvvBOKiopEeWfOnImvvfYadO/eHVRVFeFj0cShigx+FS8gHA7D+fPnYeXKlfDYY4+lRZ8i9u3bh6NGjQKn0wl+v1+4MLaC1+sFTdOgrKwMBg0alFblisfAgQMxPz8fhg0bBqNGjYLevXuLGBY0HyiKAs3NzXD8+HERVrkj3OraZd68eTh37lyYNGkS9OjRQ7idjXQnazX4SjQi+3+s+YbmJUVRoKamBmpra+FPf/oTvPLKK+2uz7RskMGDB+Ott94K06ZNg+uuuw6ysrIgMzNTDC5ZKNXU1MCxY8dg165dsGHDBjhw4EBalsmMvLw8nD59OgwYMACGDh0KvXv3hqysLMMkYmUijoX+le932b+6THV1NdTU1EBZWRkUFRXB7t27DRP4xcLw4cMxGYI8GAxCVlYWqKoKR44cSVm9DBgwAFMhyOWAOhQPHQBMyzp48GB0u91w5MgRx5AhQ1AOuBIN8minaRr4fD44dOhQ2vUtMtL65JNPHCNGjECAlgh28RYq4XAY/vWvfzlGjRqFdiMApiMDBgzArl27gqqqadlWbeG2227DiRMnwrBhw+DKK6+Eyy+/HDp37gwAiZlf5SBLAGCYg9xuNzQ3N0NdXR18+eWXUFJSAoWFhVBYWAiffPJJwur3ommoSZMmYc+ePUXFnD9/Hurr6+Hjjz++aMpglbFjx2LXrl3B6/W2e8VIgWIospWmaRAIBKCxsRECgUBCI8AxDMNcDIwcORIzMjKgT58+7XqOvGGgXb6u6yIwUHV1Nezfv5/nWIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGIZhGKaN/D/Kmxgrr6uDLQAAAABJRU5ErkJggg=="; function f(a){ doc.setFillColor(a[0],a[1],a[2]); } function t(a){ doc.setTextColor(a[0],a[1],a[2]); } function d(a){ doc.setDrawColor(a[0],a[1],a[2]); } function fP(n){ return isNaN(n)||!isFinite(n)?'$0':'$'+Math.round(n).toLocaleString('es-CL'); } function pP(n){ return isNaN(n)||!isFinite(n)?'0.0%':n.toFixed(1)+'%'; } function vC(v,thr){ return v>=thr?POS:v>0?WRN:NEG; } // ── Page state ── let curY = 0; const FOOTER_H = 12; const SAFE_BOTTOM = H - FOOTER_H - 4; function ensureSpace(needed) { if (curY + needed > SAFE_BOTTOM) { addPageContinue(); } } function addPageContinue() { pageFooter(doc.internal.getCurrentPageInfo().pageNumber, '...'); doc.addPage(); bgPage(); curY = 14; } function bgPage() { f(BG); doc.rect(0,0,W,H,'F'); } function pageFooter(pg, total) { f(BG2); doc.rect(0,H-FOOTER_H,W,FOOTER_H,'F'); t(MUT2); doc.setFontSize(6.5); doc.setFont('helvetica','normal'); doc.text('Centro de análisis de costos & Pricing — Volcano', ML, H-4); doc.text('Pág. '+pg+(total!=='...'?' de '+total:'')+' · '+now, MR, H-4, {align:'right'}); } // Wrap-aware alert box — returns new Y function alertBox(x, y, w, text, type) { const bgC = type==='ok'?POS_BG : type==='warn'?WRN_BG : NEG_BG; const bdC = type==='ok'?POS_BD : type==='warn'?WRN_BD : NEG_BD; const txC = type==='ok'?POS : type==='warn'?WRN : NEG; const lines = doc.splitTextToSize(text, w-10); const boxH = Math.max(12, lines.length*4.8 + 6); ensureSpace(boxH + 3); f(bgC); doc.rect(x,curY,w,boxH,'F'); f(bdC); doc.rect(x,curY,2.5,boxH,'F'); d(bdC); doc.setLineWidth(0.25); doc.rect(x,curY,w,boxH,'S'); t(txC); doc.setFontSize(7.5); doc.setFont('helvetica','normal'); doc.text(lines, x+5, curY+5.5, {lineHeightFactor:1.4}); curY += boxH + 4; } // Section header bar function sectionBar(label) { ensureSpace(12); f(SURF); doc.rect(ML,curY,CW,7,'F'); f(ACC); doc.rect(ML,curY,2.5,7,'F'); t(WHT); doc.setFontSize(8); doc.setFont('helvetica','bold'); doc.text(label, ML+5, curY+5); curY += 11; } // KV card — returns next x (horizontal flow) function kvCard(x, y, w, label, val, valC) { f(SURF2); doc.rect(x,y,w-1,14,'F'); t(MUT); doc.setFontSize(6); doc.setFont('helvetica','normal'); doc.text(label, x+2, y+4.5); t(valC||WHT); doc.setFontSize(9); doc.setFont('helvetica','bold'); doc.text(val, x+2, y+11.5); } // Table row function tableRow(label, val, valC, indent, subtotal) { const rowH = 6.5; ensureSpace(rowH + 1); if(subtotal){ f(SURF2); doc.rect(ML,curY-1,CW,rowH+1,'F'); } t(indent?MUT2:MUT); doc.setFontSize(7.5); doc.setFont('helvetica', subtotal?'bold':'normal'); const maxW = CW - 35; const lbl = doc.splitTextToSize(label, maxW - (indent?8:0)); doc.text(lbl, ML+(indent?6:2), curY+1.5); t(valC||WHT); doc.setFont('helvetica','bold'); doc.text(val, MR-2, curY+1.5, {align:'right'}); d(SURF2); doc.setLineWidth(0.15); doc.line(ML, curY+rowH-1, MR, curY+rowH-1); curY += rowH; } function grandTotal(label, val) { ensureSpace(18); f(SURF2); doc.rect(ML,curY,CW,14,'F'); d(ACC); doc.setLineWidth(0.4); doc.rect(ML,curY,CW,14,'S'); t(MUT); doc.setFontSize(7); doc.setFont('helvetica','normal'); doc.text(label, ML+3, curY+5.5); t(WHT); doc.setFontSize(16); doc.setFont('helvetica','bold'); doc.text(val, MR-2, curY+11, {align:'right'}); curY += 18; } function bodyText(text) { const lines = doc.splitTextToSize(text, CW); const needed = lines.length * 4.5 + 4; ensureSpace(needed); t(MUT); doc.setFontSize(7.5); doc.setFont('helvetica','normal'); doc.text(lines, ML, curY, {lineHeightFactor:1.4}); curY += needed; } function flowStrip(items) { ensureSpace(20); const fw = CW / items.length; items.forEach((fi,i)=>{ const hi = fi.hi; f(hi?SURF2:SURF); doc.rect(ML+i*fw,curY,fw-1,15,'F'); if(hi){ d(ACC); doc.setLineWidth(0.3); doc.rect(ML+i*fw,curY,fw-1,15,'S'); } t(MUT); doc.setFontSize(6); doc.setFont('helvetica','normal'); doc.text(fi.l, ML+i*fw+(fw-1)/2, curY+5, {align:'center'}); t(hi?WHT:ACC); doc.setFontSize(8.5); doc.setFont('helvetica','bold'); doc.text(fi.v, ML+i*fw+(fw-1)/2, curY+12, {align:'center'}); }); curY += 20; } function kvGrid(items, cols) { const colW = CW / cols; const rows = Math.ceil(items.length / cols); ensureSpace(rows * 16); items.forEach((it,i)=>{ const col = i % cols; const row = Math.floor(i / cols); kvCard(ML+col*colW, curY+row*16, colW, it.l, it.v, it.c); }); curY += rows * 16 + 4; } const PAGES = 6; // ═══════════════════════════════════════════ // PAGE 1 — PORTADA // ═══════════════════════════════════════════ bgPage(); // Top accent f(ACC); doc.rect(0,0,W,2,'F'); // Logo top-right try { doc.addImage(LOGO_B64,'PNG', W-62, 8, 50, 20); } catch(e) { /* logo optional */ } // Title block f(SURF); doc.rect(0,40,W,55,'F'); f([60,60,60]); doc.rect(0,40,3,55,'F'); t(MUT); doc.setFontSize(8); doc.setFont('helvetica','normal'); doc.text('ANÁLISIS DE COSTOS & PRICING', W/2, 36, {align:'center'}); t(WHT); doc.setFontSize(22); doc.setFont('helvetica','bold'); doc.text('Centro de análisis de', W/2, 54, {align:'center'}); doc.text('costos & Pricing', W/2, 67, {align:'center'}); t(MUT); doc.setFontSize(9); doc.setFont('helvetica','normal'); doc.text('Estrategia de pricing para posicionamiento web', W/2, 80, {align:'center'}); // Summary KVs curY = 105; kvGrid([ {l:'Costo neto', v:fP(s.costo), c:ACC}, {l:'Margen objetivo', v:pP(s.tgt), c:ACC}, {l:'PVP a publicar ML', v:fP(s.pvpML), c:WHT}, {l:'PVP web', v:fP(s.comp), c:WHT}, {l:'PVP NETO (sin IVA)', v:fP(s.pvpNeto), c:ACC}, {l:'PVP BRUTO (con IVA)',v:fP(s.pvpBruto), c:ACC}, ], 3); // Verdict alertBox(ML, curY, CW, s.diffComp<=0 ? '✓ Tu PVP óptimo ('+fP(s.pvpML)+') es '+fP(Math.abs(s.diffComp))+' más económico que el PVP web ('+fP(s.comp)+'). Precio competitivo con margen asegurado del '+pP(s.tgt)+'.' : '⚑ Tu PVP óptimo ('+fP(s.pvpML)+') está '+fP(s.diffComp)+' sobre el PVP web ('+fP(s.comp)+'). Evalúa reducir el costo de envío o ajustar el margen objetivo para mejorar tu competitividad.', s.diffComp<=0?'ok':'warn' ); // Contents list ensureSpace(60); t(MUT); doc.setFontSize(7); doc.setFont('helvetica','normal'); doc.text('CONTENIDO', ML, curY); curY += 5; ['1. Portada y resumen ejecutivo','2. Parámetros base y configuración','3. Construcción del precio óptimo','4. Pricing Test','5. Análisis de competencia','6. Escenarios de costo de envío'] .forEach((pg,i)=>{ f(i===0?SURF2:SURF); doc.rect(ML,curY,CW,7.5,'F'); t(i===0?ACC:MUT); doc.setFontSize(7.5); doc.setFont('helvetica',i===0?'bold':'normal'); doc.text(pg, ML+3, curY+5.2); curY += 8; }); pageFooter(1, PAGES); // ═══════════════════════════════════════════ // PAGE 2 — PARÁMETROS // ═══════════════════════════════════════════ doc.addPage(); bgPage(); f(ACC); doc.rect(0,0,W,2,'F'); // small logo header try { doc.addImage(LOGO_B64,'PNG', W-50, 4, 36, 14); } catch(e){} curY = 18; sectionBar('PARÁMETROS BASE'); kvGrid([ {l:'Costo neto', v:fP(s.costo), c:ACC}, {l:'Costo + IVA', v:fP(s.costoIva), c:WHT}, {l:'Comisión ML', v:pP(s.pct), c:MUT}, {l:'Cargo fijo ML', v:fP(s.fijo), c:MUT}, {l:'Costo envío', v:fP(s.ship), c:MUT}, {l:'IVA aplicado', v:pP(s.iva), c:MUT}, {l:'PVP web', v:fP(s.comp), c:WHT}, {l:'Margen objetivo', v:pP(s.tgt), c:ACC}, ], 4); sectionBar('FÓRMULA APLICADA'); f(SURF2); doc.rect(ML,curY,CW,18,'F'); t(MUT); doc.setFontSize(7); doc.setFont('helvetica','normal'); doc.text('La fórmula de margen sobre ventas calcula el porcentaje de ganancia sobre el precio de venta (no sobre el costo de compra).', ML+3, curY+5); t(ACC); doc.setFontSize(8); doc.setFont('helvetica','bold'); doc.text('PVP NETO = Costo ÷ (1 − margen%)', ML+3, curY+11); doc.text('PVP BRUTO = PVP NETO × (1 + IVA%)', ML+3+85, curY+11); doc.text('PVP ML = (PVP NETO + Fijo + Envío) ÷ (1 − comisión%)', ML+3, curY+16); curY += 22; bodyText('Con un costo neto de '+fP(s.costo)+' y un IVA del '+pP(s.iva)+', el desembolso real asciende a '+fP(s.costoIva)+'. La comisión de ML del '+pP(s.pct)+' se aplica sobre el PVP publicado. Sumado al cargo fijo de '+fP(s.fijo)+' y el costo de envío de '+fP(s.ship)+', el total de fees ML por venta es '+fP(s.totalFees)+'.'); pageFooter(2, PAGES); // ═══════════════════════════════════════════ // PAGE 3 — PRECIO ÓPTIMO // ═══════════════════════════════════════════ doc.addPage(); bgPage(); f(ACC); doc.rect(0,0,W,2,'F'); try { doc.addImage(LOGO_B64,'PNG', W-50, 4, 36, 14); } catch(e){} curY = 18; sectionBar('CONSTRUCCIÓN DEL PRECIO ÓPTIMO — '+activeMkp.toUpperCase()+' · '+pP(s.tgt)+' margen s/ventas'); flowStrip([ {l:'Costo NETO', v:fP(s.costo), hi:false}, {l:'÷ (1−'+s.tgt+'%)',v:'÷'+(1-s.m).toFixed(2), hi:false}, {l:'= PVP NETO', v:fP(s.pvpNeto), hi:true}, {l:'+ IVA '+s.iva+'%',v:'+'+fP(s.ivaAmt),hi:false}, {l:'= PVP BRUTO', v:fP(s.pvpBruto), hi:true}, ]); sectionBar('DESGLOSE DETALLADO'); tableRow('Costo neto del producto', fP(s.costo), MUT, false, false); tableRow('÷ (1 − '+s.tgt+'%) — margen sobre ventas','÷'+(1-s.m).toFixed(2), MUT2, true, false); tableRow('= PVP NETO (ganancia incluida)', fP(s.pvpNeto), ACC, false, true); tableRow(' Ganancia contenida en PVP NETO', '+'+fP(s.ganancia), POS, true, false); tableRow('+ IVA ('+s.iva+'%)', '+'+fP(s.ivaAmt),MUT, false, false); tableRow('= PVP BRUTO base (igual a planilla)', fP(s.pvpBruto), ACC, false, true); tableRow('− Comisión ML ('+s.pct+'% del PVP publicado)','−'+fP(s.comML), NEG, true, false); tableRow('− Cargo fijo ML', '−'+fP(s.fijo), NEG, true, false); tableRow('− Envío Mercado Envíos', '−'+fP(s.ship), NEG, true, false); tableRow('Total fees ML por venta', '−'+fP(s.totalFees),NEG,false,true); curY += 2; grandTotal('PVP A PUBLICAR EN ML', fP(s.pvpML)); alertBox(ML, curY, CW, s.diffComp<=0 ? '✓ '+fP(Math.abs(s.diffComp))+' más económico que el PVP web ('+fP(s.comp)+'). Precio competitivo con el margen del '+pP(s.tgt)+' garantizado.' : '⚑ '+fP(s.diffComp)+' sobre el PVP web ('+fP(s.comp)+'). Para competir directamente, reduce el envío o negocia mejor precio de compra.', s.diffComp<=0?'ok':'warn' ); bodyText('El margen del '+pP(s.tgt)+' significa que de cada '+fP(s.pvpNeto)+' recibidos de ML, '+fP(s.ganancia)+' corresponde a ganancia neta antes de IVA. El PVP de '+fP(s.pvpML)+' publicado en ML ya incluye el margen objetivo y absorbe todos los fees de la plataforma.'); pageFooter(3, PAGES); // ═══════════════════════════════════════════ // PAGE 4 — TESTEADOR // ═══════════════════════════════════════════ doc.addPage(); bgPage(); f(ACC); doc.rect(0,0,W,2,'F'); try { doc.addImage(LOGO_B64,'PNG', W-50, 4, 36, 14); } catch(e){} curY = 18; sectionBar('PRICING TEST — PVP analizado: '+fP(s.testPvp)); kvGrid([ {l:'Comisión ML', v:'−'+fP(s.tCom), c:NEG}, {l:'Cargo fijo', v:'−'+fP(s.fijo), c:NEG}, {l:'Envío', v:'−'+fP(s.ship), c:NEG}, {l:'Total fees', v:'−'+fP(s.tFees), c:NEG}, {l:'$ A recibir', v:fP(s.tRecv), c:ACC}, ], 5); kvGrid([ {l:'Costo neto', v:fP(s.costo), c:MUT}, {l:'Ganancia neta $', v:(s.tProfit>=0?'':'-')+fP(Math.abs(s.tProfit)), c:s.tProfit>=0?POS:NEG}, {l:'Margen s/ventas', v:pP(s.tMV), c:vC(s.tMV,s.tgt)}, {l:'Margen s/costo', v:pP(s.tMC), c:vC(s.tMC,s.tgt)}, {l:'Margen s/IVA', v:pP(s.tMI), c:vC(s.tMI,s.tgt)}, ], 5); // Distribution bar ensureSpace(20); t(MUT); doc.setFontSize(7); doc.setFont('helvetica','normal'); doc.text('Distribución del PVP '+fP(s.testPvp), ML, curY); curY += 5; const pvpS = Math.max(s.testPvp,1); const cBW = Math.max(0, Math.min(CW, CW * s.costo/pvpS)); const pBW = Math.max(0, Math.min(CW-cBW, CW * Math.max(0,s.tProfit)/pvpS)); const fBW = Math.max(0, Math.min(CW-cBW-pBW, CW * s.tFees/pvpS)); f([139,0,38]); doc.rect(ML, curY, cBW, 7,'F'); f([201,168,76]); doc.rect(ML+cBW, curY, pBW, 7,'F'); f([150,50,50]); doc.rect(ML+cBW+pBW,curY,fBW, 7,'F'); curY += 10; [[[ 40,100,40],'Costo '+(cBW/CW*100).toFixed(1)+'%'], [[80,80,180], 'Ganancia '+(pBW/CW*100).toFixed(1)+'%'], [[150,50,50], 'Fees ML '+(fBW/CW*100).toFixed(1)+'%'] ].forEach(([col,lbl],i)=>{ f(col); doc.circle(ML+4+i*62, curY+2, 2,'F'); t(MUT); doc.setFontSize(7); doc.text(lbl, ML+9+i*62, curY+3.5); }); curY += 10; alertBox(ML, curY, CW, s.tMV>=s.tgt ? '✓ A '+fP(s.testPvp)+' logras '+pP(s.tMV)+' de margen sobre ventas, superando el objetivo del '+pP(s.tgt)+'. Ganancia neta de '+fP(s.tProfit)+' por unidad vendida.' : s.tProfit>0 ? '↗ A '+fP(s.testPvp)+' el margen es '+pP(s.tMV)+', por debajo del '+pP(s.tgt)+' objetivo. Hay ganancia de '+fP(s.tProfit)+', pero insuficiente. Sube el precio a '+fP(s.pvpML)+' para alcanzar el objetivo.' : '⚠ A '+fP(s.testPvp)+' las fees de ML superan lo recibido. Pérdida de '+fP(Math.abs(s.tProfit))+' por unidad. PVP mínimo viable con margen '+pP(s.tgt)+': '+fP(s.pvpML)+'.', s.tMV>=s.tgt?'ok':s.tProfit>0?'warn':'error' ); pageFooter(4, PAGES); // ═══════════════════════════════════════════ // PAGE 5 — COMPETIDORES // ═══════════════════════════════════════════ doc.addPage(); bgPage(); f(ACC); doc.rect(0,0,W,2,'F'); try { doc.addImage(LOGO_B64,'PNG', W-50, 4, 36, 14); } catch(e){} curY = 18; sectionBar('ANÁLISIS DE COMPETENCIA — '+s.compList.length+' competidores · Mi PVP: '+fP(s.pvpML)); if (s.compList.length === 0) { ensureSpace(18); f(SURF); doc.rect(ML,curY,CW,14,'F'); t(MUT); doc.setFontSize(9); doc.setFont('helvetica','normal'); doc.text('Sin competidores registrados en este análisis.', W/2, curY+9, {align:'center'}); curY += 18; } else { const cpvps = s.compList.map(c2=>parseFloat(c2.pvp)).filter(v=>v>0); if (cpvps.length > 0) { const minC=Math.min(...cpvps), maxC=Math.max(...cpvps); const avgC=cpvps.reduce((a,b)=>a+b,0)/cpvps.length; kvGrid([ {l:'Mínimo competencia', v:fP(minC), c:NEG}, {l:'Máximo competencia', v:fP(maxC), c:ACC}, {l:'Promedio competencia',v:fP(avgC), c:MUT}, {l:'Mi PVP óptimo ML', v:fP(s.pvpML), c:WHT}, ], 4); } // Table header ensureSpace(10); f(SURF); doc.rect(ML,curY,CW,7,'F'); t(MUT2); doc.setFontSize(6.5); doc.setFont('helvetica','bold'); doc.text('NOMBRE', ML+2, curY+4.8); doc.text('PVP', ML+72, curY+4.8); doc.text('DIFERENCIA', ML+100, curY+4.8); doc.text('URL', ML+145, curY+4.8); curY += 9; s.compList.forEach((comp2,i)=>{ const cpv = parseFloat(comp2.pvp); const diff = cpv - s.pvpML; const dc = diff<0?POS:diff>0?NEG:WRN; ensureSpace(9); if(i%2===0){ f(SURF); doc.rect(ML,curY-2,CW,7.5,'F'); } t(WHT); doc.setFontSize(7.5); doc.setFont('helvetica','bold'); doc.text((comp2.name||'Comp.'+(i+1)).slice(0,24), ML+2, curY+2); t(ACC); doc.text(fP(cpv), ML+72, curY+2); t(dc); doc.text(diff<0?'-'+fP(Math.abs(diff)):diff>0?'+'+fP(diff):'≈ igual', ML+100, curY+2); t(MUT2); doc.setFontSize(6); doc.setFont('helvetica','normal'); doc.text((comp2.url||'—').slice(0,38), ML+145, curY+2); curY += 7.5; }); curY += 4; } const cheaper5 = s.compList.filter(c2=>parseFloat(c2.pvp){ const ok2 = sc.pvpNeeded <= s.comp && s.comp > 0; ensureSpace(40); f(SURF); doc.rect(ML,curY,CW,36,'F'); f(ok2?[30,70,30]:[70,50,15]); doc.rect(ML,curY,2.5,36,'F'); t(WHT); doc.setFontSize(8.5); doc.setFont('helvetica','bold'); doc.text(sc.label, ML+5, curY+7); t(ok2?POS:WRN); doc.setFontSize(7); doc.setFont('helvetica','normal'); doc.text(ok2?'✓ '+pP(s.tgt)+' alcanzable bajo PVP web':'⚑ '+pP(s.tgt)+' requiere subir el precio publicado', ML+5, curY+13); const sc4 = (CW-10)/4; [ {l:'Costo envío', v:fP(sc.ship), c:MUT}, {l:'Ganancia neta', v:(sc.profit>=0?'':'-')+fP(Math.abs(sc.profit)), c:sc.profit>=0?POS:NEG}, {l:'Margen s/ventas', v:sc.mVentas>-900?pP(sc.mVentas):'—', c:vC(sc.mVentas,s.tgt)}, {l:'PVP necesario', v:fP(sc.pvpNeeded), c:ok2?POS:WRN}, ].forEach((it,j)=>{ t(MUT2); doc.setFontSize(6); doc.setFont('helvetica','normal'); doc.text(it.l, ML+5+j*sc4, curY+22); t(it.c); doc.setFontSize(9); doc.setFont('helvetica','bold'); doc.text(it.v, ML+5+j*sc4, curY+30); }); curY += 40; }); curY += 4; bodyText('El costo de envío es el factor más determinante para la competitividad del precio. Un producto liviano (<500g) puede tener tarifa ~$800, permitiendo lograr el '+pP(s.tgt)+' de margen a un precio inferior al PVP PVP web. Verifica la tarifa exacta en tu cuenta MercadoLibre → Tarifas de envío, ingresando el peso y dimensiones reales del embalaje.'); ensureSpace(16); f(SURF2); doc.rect(ML,curY,CW,12,'F'); t(MUT2); doc.setFontSize(6.5); doc.setFont('helvetica','normal'); doc.text('FÓRMULAS · PVP NETO = Costo ÷ (1−margen%) · PVP BRUTO = PVP NETO × (1+IVA%) · PVP ML = (PVP NETO + Fijo + Envío) ÷ (1−Comisión%)', ML+3, curY+7.5); curY += 16; pageFooter(6, PAGES); // ── Save ── doc.save('volcano-pricing-'+new Date().toISOString().slice(0,10)+'.pdf'); btn.disabled = false; st.textContent = '✓ PDF descargado correctamente'; st.className = 'export-status ok'; setTimeout(()=>{ st.textContent=''; st.className='export-status'; }, 5000); } catch(err) { btn.disabled = false; st.textContent = '✗ Error: ' + err.message; st.className = 'export-status err'; console.error('[PDF]', err); } }