- Updated proforma listing behavior to utilize `Criteria filters[]` for managing archived and active proformas. - Removed `archived` query parameter from backend; frontend now manages `archiveView` state. - Implemented new filters for `archived_at` and `status` in the proforma listing API. - Adjusted proforma creation and deletion contracts to reflect changes in archiving logic. - Introduced new utility functions for building proforma listing criteria based on UI state. - Updated frontend components to support new filtering options and maintain state in the URL. - Added SQL index for improved performance on proforma queries. - Created new TypeScript types for managing proforma list filters and criteria.
4.6 KiB
4.6 KiB
Proforma Create Contract
Objetivo
Definir la semantica correcta de create proforma como creacion de cabecera inicial y separarla del calculo fiscal real que depende de lineas valoradas.
Regla principal
tax_regime_code no es un impuesto aplicado.
En create:
taxRegimeCoderepresenta configuracion fiscal inicialtax_configrepresenta la configuracion fiscal persistida de cabecerataxesrepresenta impuestos realmente calculados desde lineas valoradastotalsrepresenta importes realmente calculados desde lineas valoradastax_modepor defecto essingle
Contrato funcional de create
Una proforma puede crearse sin lineas.
Si items se omite o se envia como []:
- la proforma debe crearse correctamente como borrador
- debe generarse
proforma_reference - pueden resolverse defaults comerciales y fiscales iniciales
itemsdebe devolverse como[]taxesdebe devolverse como[]- los totales monetarios deben devolverse a
0 - no deben crearse filas artificiales en
proforma_taxes
Payload minimo esperado
{
proforma_date: string;
customer_id: string;
proforma_series_code?: string | null;
target_invoice_series_code?: string | null;
currency_code?: string;
payment_method_id?: string | null;
payment_term_id?: string | null;
tax_regime_code?: string | null;
tax_config?: {
tax_mode?: "single" | "per_line";
default_iva_code?: string | null;
uses_equivalence_surcharge?: boolean;
default_rec_code?: string | null;
uses_retention?: boolean;
default_retention_code?: string | null;
};
items?: [];
}
Notas:
- el contrato actual del modulo puede seguir exigiendo otros campos tecnicos ya existentes
itemses opcional; si existe, puede ir vacio- no se usan defaults ocultos en Zod para disfrazar la intencion del request
- si no se informa
tax_config, el backend resuelve defaults iniciales y los persiste - si el cliente cambia después, la proforma conserva su
tax_configpersistido
Response esperada al crear sin lineas
Adaptando nombres exactos al contrato publico actual:
{
id: string;
proforma_reference: string;
proforma_date: string;
customer_id: string;
currency_code: string;
payment_method_id: string | null;
payment_term_id: string | null;
tax_regime_code: string | null;
target_invoice_series_code: string | null;
items: [];
taxes: [];
totals: {
subtotal_before_discounts: "0.00";
line_discount_total: "0.00";
taxable_base: "0.00";
tax_total: "0.00";
total: "0.00";
};
}
Punto correcto de calculo
createcrea cabecera minima, numera y resuelve defaultscreatepersiste tambien eltax_configresueltoupdatepermite anadir o editar lineas- al existir lineas valoradas,
updaterecalculataxesytotals issuegenera laissued_invoicematerializada usandotarget_invoice_series_codesi existe y, si no, la default activa deissued_invoice
Relacion con borrado
- una proforma creada en
draftpuede borrarse logicamente mas adelante - ese borrado no modifica
tax_config, impuestos, totales ni numeracion historica - la referencia visible consumida por create no vuelve a reutilizarse aunque la proforma se borre
Wording de UI
La UI de create debe hablar de:
- "Se preparara automaticamente"
- "valores iniciales"
- "configuracion fiscal inicial"
La UI no debe sugerir:
- que los impuestos ya quedaron aplicados al crear
- que existe desglose fiscal real sin lineas
- que los totales ya fueron calculados si todavia no hay lineas valoradas
Diagnostico SQL recomendado
SELECT
p.id,
p.proforma_reference,
COUNT(DISTINCT pi.item_id) AS item_rows,
COUNT(DISTINCT pt.tax_id) AS tax_rows
FROM proformas p
LEFT JOIN proforma_items pi
ON pi.proforma_id = p.id
LEFT JOIN proforma_taxes pt
ON pt.proforma_id = p.id
GROUP BY p.id, p.proforma_reference
HAVING COUNT(DISTINCT pi.item_id) = 0
AND COUNT(DISTINCT pt.tax_id) > 0;
Resultado esperado:
0filas
Si devuelve filas:
- documentar los ids afectados
- revisar si provienen de datos legacy o de una version intermedia del flujo
- no borrar datos sin confirmacion explicita
Pendientes conocidos
payment_term_idaparece ya en contratos de transporte, pero el dominio/snapshot de proformas sigue sin soporte funcional completo en esta fase- no se introduce un motor fiscal nuevo en este ajuste
Archivado
- una proforma creada nace con
archived_at = NULL - el archivado posterior no altera
status - una proforma
draftarchivada puede borrarse sin desarchivarse antes - en listados, la visibilidad archivada se expresa mediante
Criteria filters[]sobrearchived_at, no mediante un estado de negocio nuevo