diff --git a/frontend/src/components/CortePrint.tsx b/frontend/src/components/CortePrint.tsx new file mode 100644 index 0000000..5ef17fd --- /dev/null +++ b/frontend/src/components/CortePrint.tsx @@ -0,0 +1,115 @@ +import type { FC } from 'react'; +import { Printer } from 'lucide-react'; +import { Button, Modal } from './ui'; +import type { CashClosing } from '../services/odoo'; + +// Corte de caja imprimible. Sigue el patrón de impresión existente +// (RecetaPrint / EstadoCuentaPrint / TicketPrint): contenido en un +// div.print-ticket + window.print(); el CSS de @media print en index.css +// oculta el resto de la página. + +interface ClinicSettings { + name: string; + phone: string; + address: string; +} + +const clinicSettings = (): ClinicSettings => { + try { + const saved = localStorage.getItem('skeen_clinic_settings'); + if (saved) return JSON.parse(saved); + } catch { + // ignore + } + return { name: 'SKEEN Derma Experts', phone: '', address: '' }; +}; + +const money = (v: number) => + '$' + (v ?? 0).toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); + +export const CortePrint: FC<{ corte: CashClosing | null; onClose: () => void }> = ({ corte, onClose }) => { + if (!corte) return null; + const clinic = clinicSettings(); + + const fila = (label: string, valor: number) => ( +
{clinic.name}
+ {clinic.address &&{clinic.address}
} + {clinic.phone &&{clinic.phone}
} +CORTE DE CAJA {corte.name}
+Fecha: {corte.date} · Cerró: {corte.user || '—'}
+| Método | +Esperado | +Contado | +Diferencia | +
|---|---|---|---|
| Diferencia total del corte | +0 ? 'text-emerald-700' : '')}> + {corte.difference > 0 ? '+' : ''}{money(corte.difference)} + | +
Notas:
+{corte.notes}
+Impreso el {new Date().toLocaleString('es-MX')}
++ {key === 'cash' ? 'Efectivo esperado (apertura + cobros)' : `${titulo} registrado en el sistema`} +
+{money(esp)}
+{cont > 0 || values[key] ? 'Diferencia' : 'Aún sin contar'}
++ {values[key] ? `${diff > 0 ? 'Sobrante +' : diff < 0 ? 'Faltante ' : ''}${money(diff)}` : '—'} +
++ {diff === 0 && 'El efectivo cuadra.'} + {diff < 0 && `Faltan ${money(-diff)} en la caja.`} + {diff > 0 && `Sobran ${money(diff)} en la caja.`} +
+ )} +| Método | +Esperado | +Contado | +Diferencia | +
|---|---|---|---|
| {titulo} | +{money(esp)} | +{money(cont)} | ++ {diff > 0 ? '+' : ''}{money(diff)} + | +
- Corte: {closeOpen.name} + Ventas del día: {money(wizard.total_sales)} + {' · '}Fondo inicial: {money(wizard.opening_cash)}
-- Ventas registradas: ${closeOpen.total_sales} -
- setClosingCash(e.target.value)} - /> + {renderPaso()}