feat(web): lotes y series en las líneas de entradas, salidas y transferencias de stock

Una ventana por línea con tabla editable; validación de suma de lotes y una serie por unidad.
Probado contra SBODemoCL: entrada de inventario 156 con SU01 y su lote.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-16 12:25:01 -05:00
1 parent a5592fac76
commit abc1cc4ac6
16 files changed
+752 -10

No files matched your search

@@ -1,4 +1,4 @@
import type { GridColumn, GridLine } from '../../shared/grid/grid.types';
import type { GridColumn, GridDetail, GridLine } from '../../shared/grid/grid.types';
import type { ListColumn } from '../../shared/list/list.types';
import type { VhLookup } from '../../shared/value-help/value-help.types';
import type { DocRecord, LinesSpec } from './document-model';
@@ -73,6 +73,8 @@ export interface DocumentLayout {
newLine: (header: DocRecord) => GridLine;
/** Recalcula una línea tras un cambio (total = cantidad × precio…); recibe la tasa de cada código de impuesto. */
recalc?: (line: GridLine, changedKey: string, rates?: ReadonlyMap<string, number>) => GridLine;
/** Detalles de línea (lotes, series) que este documento permite indicar. */
details?: readonly GridDetail[];
/** Campos de cabecera que se ven pero no se editan (un cliente puede querer verlos sin cambiarlos). */
lockedKeys?: readonly string[];
/** Subtipo con que SAP etiqueta las series de este documento (`--` = ninguno, `IB` = boleta…). */
@@ -131,7 +133,14 @@ export function itemColumnWithUom(item: GridColumn, side: 'purchase' | 'sales'):
...item,
lookup: {
...item.lookup!,
apply: (picked, line) => ({ ...item.lookup!.apply(picked, line), UoMEntry: uomEntryOf(picked, side) }),
apply: (picked, line) => ({
...item.lookup!.apply(picked, line),
UoMEntry: uomEntryOf(picked, side),
// Lotes y series: si el artículo se gestiona por ellos la línea los pide; al cambiar de artículo se descartan.
_manageBatches: picked['ManageBatchNumbers'] === 'tYES',
_manageSerials: picked['ManageSerialNumbers'] === 'tYES',
...(picked['ItemCode'] === line['ItemCode'] ? {} : { BatchNumbers: undefined, SerialNumbers: undefined }),
}),
},
};
}