feat: solicitudes de compra como documento de marketing (solicitante, válido hasta, fecha necesaria, proveedor y fecha por línea) y API de usuarios con campos limitados

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-19 14:53:59 -05:00
1 parent a3bd976bbd
commit c1f2cea1e1
19 files changed
+342 -62

No files matched your search

+2 -2
View File
@@ -19,8 +19,8 @@ export interface GridColumn {
width?: string;
/** Alineación del texto de la columna (encabezado y celdas); por defecto, `right` en las numéricas y `left` en el resto. */
align?: 'left' | 'center' | 'right';
/** `number` se alinea a la derecha, se muestra con formato y se interpreta al salir de la celda. */
type?: 'text' | 'number';
/** `number` se alinea a la derecha, se muestra con formato y se interpreta al salir de la celda; `date` es una fecha (`yyyy-MM-dd`, la de SAP sin hora). */
type?: 'text' | 'number' | 'date';
/** Decimales fijos para `number` (importes: 2); sin él, hasta 3 sin ceros sobrantes. */
decimals?: number;
/** No editable (siempre, o según la línea). */
+1 -1
View File
@@ -51,7 +51,7 @@
} @else {
<input
class="cell"
type="text"
[attr.type]="c.type === 'date' ? 'date' : 'text'"
autocomplete="off"
[style.text-align]="alignOf(c)"
[class.mono]="c.mono"
@@ -662,3 +662,22 @@ describe('LinesGrid: celdas de cuenta', () => {
expect(cell().value).toBe('1071111010');
});
});
describe('LinesGrid: columna de fecha', () => {
it('muestra la fecha de SAP sin hora, en un campo de fecha, y guarda la que se elige', async () => {
await TestBed.configureTestingModule({ imports: [Host], providers: [provideHttpClient(), provideHttpClientTesting()] }).compileComponents();
const fixture = TestBed.createComponent(Host);
fixture.componentInstance.columns = [{ key: 'ItemCode', title: 'Artículo' }, { key: 'RequiredDate', title: 'Fecha necesaria', type: 'date' }];
fixture.componentInstance.lines.set([{ ItemCode: 'A', RequiredDate: '2026-10-01T00:00:00Z' }]);
fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();
const input = (fixture.nativeElement as HTMLElement).querySelector<HTMLInputElement>('input[data-r="0"][data-c="1"]')!;
expect(input.type).toBe('date');
expect(input.value).toBe('2026-10-01');
input.value = '2026-11-15';
input.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(fixture.componentInstance.lines()[0]['RequiredDate']).toBe('2026-11-15');
});
});
@@ -116,6 +116,7 @@ export class LinesGrid {
if (column.format) return column.format(line);
const value = line[column.key];
if (column.type === 'number') return formatNumber(value, column.decimals);
if (column.type === 'date') return typeof value === 'string' ? value.slice(0, 10) : '';
const codes = column.lookup?.config.codes;
if (codes && typeof value === 'string' && value !== '') return codes.display(value);
return value === null || value === undefined ? '' : String(value);