feat(web): Indicador, prefijo y número del folio juntos en una fila (documentos de facturación y asiento) y las tres fechas de la cabecera en orden

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-19 14:35:54 -05:00
1 parent 1bb8efa77e
commit a74c19a139
11 files changed
+170 -19

No files matched your search

@@ -5,7 +5,7 @@ import { ActivatedRoute, Router, convertToParamMap, provideRouter } from '@angul
import { of } from 'rxjs';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { CLIENT_EXTENSIONS } from './client-extensions';
import { headerKeysOf } from './document-layouts';
import { fieldGroup, headerKeysOf } from './document-layouts';
import { lineFieldsOf } from './line-columns';
import { DocumentFormPage } from './document-form.page';
import { BASE_SCREENS, DOCUMENT_SCREENS } from './document-screens';
@@ -62,6 +62,44 @@ describe('extensiones por cliente', () => {
});
});
describe('indicador y folio juntos', () => {
it('la factura del base lleva Indicador, prefijo y número en una sola fila, en ese orden', () => {
const layout = by(BASE_SCREENS, '/ventas/facturas').layout;
const groups = layout.header.right.filter((f) => f.type === 'group');
expect(groups).toHaveLength(1);
expect(groups[0].type === 'group' && groups[0].cells.map((c) => c.key)).toEqual(['Indicator', 'FolioPrefixString', 'FolioNumber']);
expect(layout.header.left.some((f) => 'key' in f && f.key === 'Indicator')).toBe(false); // ya no va suelto
});
it('lo llevan facturas, boletas, reservas y notas de crédito de ventas y compras', () => {
for (const path of ['/ventas/facturas', '/ventas/boletas', '/ventas/facturas-reserva', '/ventas/boletas-reserva', '/ventas/notas-credito', '/compras/facturas', '/compras/notas-credito']) {
expect(by(BASE_SCREENS, path).layout.header.right.some((f) => f.type === 'group'), path).toBe(true);
}
expect(by(BASE_SCREENS, '/ventas/ordenes').layout.header.right.some((f) => f.type === 'group')).toBe(false);
});
it('una empresa con campos de usuario los sustituye por su propio grupo, también juntos', () => {
const screens = applyExtensions(BASE_SCREENS, {
'/ventas/facturas': {
hideHeaderFields: ['Indicator'], // oculta el grupo completo del base
headerRight: [
fieldGroup('Tipo / Serie / Número', [
{ kind: 'text', key: 'U_Tipo', label: 'Tipo', width: '60px' },
{ kind: 'text', key: 'U_Serie', label: 'Serie', width: '80px' },
{ kind: 'text', key: 'U_Numero', label: 'Número' },
]),
],
},
});
const layout = by(screens, '/ventas/facturas').layout;
const groups = layout.header.right.filter((f) => f.type === 'group');
expect(groups).toHaveLength(1);
expect(groups[0].type === 'group' && groups[0].cells.map((c) => c.key)).toEqual(['U_Tipo', 'U_Serie', 'U_Numero']);
expect(headerKeysOf(layout)).toEqual(expect.arrayContaining(['U_Tipo', 'U_Serie', 'U_Numero']));
expect(headerKeysOf(layout)).not.toContain('FolioNumber');
});
});
describe('formulario con campos de cliente', () => {
let fixture: ComponentFixture<DocumentFormPage>;
let ctrl: HttpTestingController;