feat(web): facturas y boletas filtran y se crean por su DocumentSubType exacto (bod_None / bod_Bill)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
52dc1957b7
commit
751857d737
2 files changed
+24
-16
No files matched your search
@@ -125,20 +125,23 @@ describe('facturas, boletas y sus reservas', () => {
|
|||||||
const by = (p: string) => DOCUMENT_SCREENS.find((s) => s.path === p)!;
|
const by = (p: string) => DOCUMENT_SCREENS.find((s) => s.path === p)!;
|
||||||
const INVOICES = ['/ventas/facturas', '/ventas/boletas', '/ventas/facturas-reserva', '/ventas/boletas-reserva'];
|
const INVOICES = ['/ventas/facturas', '/ventas/boletas', '/ventas/facturas-reserva', '/ventas/boletas-reserva'];
|
||||||
|
|
||||||
it('las cuatro comparten el recurso Invoices y se separan por ReserveInvoice y DocumentSubType', () => {
|
it('las cuatro comparten el recurso Invoices y se separan por ReserveInvoice y el subtipo exacto', () => {
|
||||||
for (const p of INVOICES) expect(by(p).resource, p).toBe('Invoices');
|
for (const p of INVOICES) expect(by(p).resource, p).toBe('Invoices');
|
||||||
// la factura solo excluye las boletas (`ne`): no pierde notas de débito ni otros subtipos
|
expect(by('/ventas/facturas').baseFilter).toBe(`ReserveInvoice eq 'tNO' and DocumentSubType eq 'bod_None'`);
|
||||||
expect(by('/ventas/facturas').baseFilter).toBe(`ReserveInvoice eq 'tNO' and DocumentSubType ne 'bod_Bill'`);
|
|
||||||
expect(by('/ventas/boletas').baseFilter).toBe(`ReserveInvoice eq 'tNO' and DocumentSubType eq 'bod_Bill'`);
|
expect(by('/ventas/boletas').baseFilter).toBe(`ReserveInvoice eq 'tNO' and DocumentSubType eq 'bod_Bill'`);
|
||||||
expect(by('/ventas/facturas-reserva').baseFilter).toBe(`ReserveInvoice eq 'tYES' and DocumentSubType ne 'bod_Bill'`);
|
expect(by('/ventas/facturas-reserva').baseFilter).toBe(`ReserveInvoice eq 'tYES' and DocumentSubType eq 'bod_None'`);
|
||||||
expect(by('/ventas/boletas-reserva').baseFilter).toBe(`ReserveInvoice eq 'tYES' and DocumentSubType eq 'bod_Bill'`);
|
expect(by('/ventas/boletas-reserva').baseFilter).toBe(`ReserveInvoice eq 'tYES' and DocumentSubType eq 'bod_Bill'`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cada una se crea con su marca y una factura normal no envía nada especial', () => {
|
it('ninguna usa «distinto de»: los demás subtipos de SAP no se mezclan en facturas ni boletas', () => {
|
||||||
const created = (p: string) => by(p).layout.beforeCreate?.({ CardCode: 'C1' });
|
for (const p of INVOICES) expect(by(p).baseFilter, p).not.toContain(' ne ');
|
||||||
expect(created('/ventas/facturas')).toBeUndefined();
|
});
|
||||||
|
|
||||||
|
it('cada una se crea con su subtipo exacto (y con ReserveInvoice si es de reserva)', () => {
|
||||||
|
const created = (p: string) => by(p).layout.beforeCreate!({ CardCode: 'C1' });
|
||||||
|
expect(created('/ventas/facturas')).toEqual({ CardCode: 'C1', DocumentSubType: 'bod_None' });
|
||||||
expect(created('/ventas/boletas')).toEqual({ CardCode: 'C1', DocumentSubType: 'bod_Bill' });
|
expect(created('/ventas/boletas')).toEqual({ CardCode: 'C1', DocumentSubType: 'bod_Bill' });
|
||||||
expect(created('/ventas/facturas-reserva')).toEqual({ CardCode: 'C1', ReserveInvoice: 'tYES' });
|
expect(created('/ventas/facturas-reserva')).toEqual({ CardCode: 'C1', ReserveInvoice: 'tYES', DocumentSubType: 'bod_None' });
|
||||||
expect(created('/ventas/boletas-reserva')).toEqual({ CardCode: 'C1', ReserveInvoice: 'tYES', DocumentSubType: 'bod_Bill' });
|
expect(created('/ventas/boletas-reserva')).toEqual({ CardCode: 'C1', ReserveInvoice: 'tYES', DocumentSubType: 'bod_Bill' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
import { TAX_DOCUMENT, type DocumentScreen, invoiceColumns, marketing, referenceColumns } from '../screen-kit';
|
import { TAX_DOCUMENT, type DocumentScreen, invoiceColumns, marketing, referenceColumns } from '../screen-kit';
|
||||||
|
|
||||||
/** Filtros que separan las cuatro pantallas de `Invoices`. */
|
/**
|
||||||
|
* Filtros que separan las cuatro pantallas de `Invoices`: `ReserveInvoice` (reserva sí/no) y el subtipo
|
||||||
|
* exacto de `DocumentSubType` (`bod_None` = factura, `bod_Bill` = boleta). Los demás subtipos de SAP
|
||||||
|
* (`bod_InvoiceExempt`, `bod_DebitMemo`, `bod_ExemptBill`, `bod_ExportInvoice`…) no se mezclan aquí:
|
||||||
|
* tendrán su propia pantalla si se necesitan.
|
||||||
|
*/
|
||||||
const RESERVE = `ReserveInvoice eq 'tYES'`;
|
const RESERVE = `ReserveInvoice eq 'tYES'`;
|
||||||
const NOT_RESERVE = `ReserveInvoice eq 'tNO'`;
|
const NOT_RESERVE = `ReserveInvoice eq 'tNO'`;
|
||||||
|
const INVOICE = `DocumentSubType eq 'bod_None'`;
|
||||||
const BILL = `DocumentSubType eq 'bod_Bill'`;
|
const BILL = `DocumentSubType eq 'bod_Bill'`;
|
||||||
const NOT_BILL = `DocumentSubType ne 'bod_Bill'`;
|
|
||||||
|
|
||||||
/** Ventas: ofertas, órdenes, entregas, facturas, devoluciones y notas de crédito de cliente. */
|
/** Ventas: ofertas, órdenes, entregas, facturas, devoluciones y notas de crédito de cliente. */
|
||||||
export const VENTAS_SCREENS: readonly DocumentScreen[] = [
|
export const VENTAS_SCREENS: readonly DocumentScreen[] = [
|
||||||
@@ -13,13 +18,13 @@ export const VENTAS_SCREENS: readonly DocumentScreen[] = [
|
|||||||
marketing('/ventas/ofertas', 'Quotations', 'Nueva oferta', 'Cliente', { columns: referenceColumns }),
|
marketing('/ventas/ofertas', 'Quotations', 'Nueva oferta', 'Cliente', { columns: referenceColumns }),
|
||||||
marketing('/ventas/ordenes', 'Orders', 'Nueva orden', 'Cliente', { columns: referenceColumns }),
|
marketing('/ventas/ordenes', 'Orders', 'Nueva orden', 'Cliente', { columns: referenceColumns }),
|
||||||
marketing('/ventas/entrega', 'DeliveryNotes', 'Nueva entrega', 'Cliente', TAX_DOCUMENT),
|
marketing('/ventas/entrega', 'DeliveryNotes', 'Nueva entrega', 'Cliente', TAX_DOCUMENT),
|
||||||
// Facturas, boletas y sus reservas son el mismo recurso (`Invoices`); se separan por dos campos:
|
// Facturas, boletas y sus reservas son el mismo recurso (`Invoices`); cada pantalla filtra por su
|
||||||
// `DocumentSubType` (`bod_Bill` = boleta) y `ReserveInvoice` (`tYES` = de reserva). La factura excluye
|
// `DocumentSubType` exacto y por `ReserveInvoice`, y envía ambos al crear.
|
||||||
// solo las boletas (`ne`, no `eq bod_None`, para no perder notas de débito u otros subtipos).
|
|
||||||
marketing('/ventas/facturas', 'Invoices', 'Nueva factura', 'Cliente', {
|
marketing('/ventas/facturas', 'Invoices', 'Nueva factura', 'Cliente', {
|
||||||
...TAX_DOCUMENT,
|
...TAX_DOCUMENT,
|
||||||
columns: invoiceColumns,
|
columns: invoiceColumns,
|
||||||
baseFilter: `${NOT_RESERVE} and ${NOT_BILL}`,
|
baseFilter: `${NOT_RESERVE} and ${INVOICE}`,
|
||||||
|
fixed: { DocumentSubType: 'bod_None' },
|
||||||
}),
|
}),
|
||||||
marketing('/ventas/boletas', 'Invoices', 'Nueva boleta', 'Cliente', {
|
marketing('/ventas/boletas', 'Invoices', 'Nueva boleta', 'Cliente', {
|
||||||
...TAX_DOCUMENT,
|
...TAX_DOCUMENT,
|
||||||
@@ -30,8 +35,8 @@ export const VENTAS_SCREENS: readonly DocumentScreen[] = [
|
|||||||
marketing('/ventas/facturas-reserva', 'Invoices', 'Nueva factura de reserva', 'Cliente', {
|
marketing('/ventas/facturas-reserva', 'Invoices', 'Nueva factura de reserva', 'Cliente', {
|
||||||
...TAX_DOCUMENT,
|
...TAX_DOCUMENT,
|
||||||
columns: invoiceColumns,
|
columns: invoiceColumns,
|
||||||
baseFilter: `${RESERVE} and ${NOT_BILL}`,
|
baseFilter: `${RESERVE} and ${INVOICE}`,
|
||||||
fixed: { ReserveInvoice: 'tYES' },
|
fixed: { ReserveInvoice: 'tYES', DocumentSubType: 'bod_None' },
|
||||||
}),
|
}),
|
||||||
marketing('/ventas/boletas-reserva', 'Invoices', 'Nueva boleta de reserva', 'Cliente', {
|
marketing('/ventas/boletas-reserva', 'Invoices', 'Nueva boleta de reserva', 'Cliente', {
|
||||||
...TAX_DOCUMENT,
|
...TAX_DOCUMENT,
|
||||||
|
|||||||
Reference in new issue
Block a user