/** * Escapa caracteres HTML para prevenir XSS. * @param {string} str El string a escapar. * @returns {string} El string escapado. */ function esc(str) { return String(str || '').replace(/[&<>"']/g, c => ({ "&": "&", "<": "<", ">": ">", "\"": """, "'": "'" }[c])); } /** * Genera el HTML para un ticket de movimiento. * @param {object} mov El objeto del movimiento. * @param {object} settings El objeto de configuración. * @returns {string} El HTML del ticket. */ function templateTicket(mov, settings) { const dt = new Date(mov.fechaISO || Date.now()); const fechaLocal = dt.toLocaleString('es-MX', { dateStyle: 'medium', timeStyle: 'short' }); const montoFormateado = Number(mov.monto).toFixed(2); const lines = []; lines.push('
'); lines.push(''); if (settings.negocio) lines.push(`
${esc(settings.negocio)}
`); if (settings.tagline) lines.push(`
${esc(settings.tagline)}
`); if (settings.rfc) lines.push(`
RFC: ${esc(settings.rfc)}
`); if (settings.sucursal) lines.push(`
${esc(settings.sucursal)}
`); if (settings.tel) lines.push(`
Tel: ${esc(settings.tel)}
`); lines.push('
'); lines.push(`
Folio:${esc(mov.folio)}
`); lines.push(`
Fecha:${esc(fechaLocal)}
`); lines.push('
'); lines.push(`
${esc(mov.tipo)}
`); if (mov.cliente) lines.push(`
Cliente: ${esc(mov.cliente)}
`); if (mov.concepto) lines.push(`
Concepto: ${esc(mov.concepto)}
`); if (mov.staff) lines.push(`
Atendió: ${esc(mov.staff)}
`); if (mov.metodo) lines.push(`
Método: ${esc(mov.metodo)}
`); if (mov.notas) lines.push(`
Notas: ${esc(mov.notas)}
`); lines.push('
'); lines.push(`
Total$${montoFormateado}
`); if (settings.leyenda) lines.push(``); lines.push('
'); return lines.join(''); } /** * Renderiza el ticket en el DOM y llama a la función de impresión del navegador. * @param {object} mov El objeto del movimiento. * @param {object} settings El objeto de configuración. */ export function renderTicketAndPrint(mov, settings) { const printArea = document.getElementById('printArea'); if (printArea) { printArea.innerHTML = templateTicket(mov, settings); window.print(); } else { console.error("El área de impresión #printArea no se encontró."); } }