feat(web): columnas de las listas de valores (cliente, artículo, almacén, impuesto) configurables por documento
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b3b47c34a3
commit
0d5a3074c8
6 files changed
+141
-12
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import type { GridColumn, 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';
|
||||
import { DOCUMENT_LINE_COLUMNS, lineColumnsFor, lineFieldsOf, newDocumentLine, recalcLine, uomEntryOf } from './line-columns';
|
||||
@@ -25,6 +26,12 @@ export type HeaderField =
|
||||
| { type: 'folio'; label: string; prefixKey: string; numberKey: string }
|
||||
| { type: 'computed'; label: string; source: ComputedSource };
|
||||
|
||||
/** Las listas de valores (ventanas modales) de un formulario. */
|
||||
export type LookupName = 'partner' | 'item' | 'warehouse' | 'tax';
|
||||
|
||||
/** Columnas que muestra cada lista de valores; la primera es el código que se escribe en el campo. */
|
||||
export type LookupColumns = Partial<Record<LookupName, readonly ListColumn[]>>;
|
||||
|
||||
export interface FieldColumns {
|
||||
/** Dos columnas como máximo (regla del proyecto base). */
|
||||
left: readonly HeaderField[];
|
||||
@@ -47,6 +54,8 @@ export interface DocumentLayout {
|
||||
newLine: (header: DocRecord) => GridLine;
|
||||
/** Recalcula una línea tras un cambio (total = cantidad × precio…). */
|
||||
recalc?: (line: GridLine, changedKey: string) => GridLine;
|
||||
/** Columnas de las listas de valores de este documento; las que falten usan las del base. */
|
||||
lookups?: LookupColumns;
|
||||
/** Una vez contabilizado ya no se modifica (SAP no permite cambiar entradas, salidas ni transferencias). */
|
||||
immutable?: boolean;
|
||||
/** Ajustes a la cabecera antes de crear. */
|
||||
@@ -91,6 +100,45 @@ export const itemColumn: GridColumn = {
|
||||
/** Lista de almacenes de la cabecera (la misma de las líneas). */
|
||||
export const WAREHOUSE_LOOKUP: VhLookup = warehouseColumn.lookup!.config;
|
||||
|
||||
/** Columnas del base de la lista de clientes y proveedores. */
|
||||
export const PARTNER_COLUMNS: readonly ListColumn[] = [
|
||||
{ key: 'CardCode', title: 'Código', width: '130px', mono: true },
|
||||
{ key: 'CardName', title: 'Nombre' },
|
||||
];
|
||||
|
||||
/** Columna de línea que abre cada lista de valores. */
|
||||
const LOOKUP_OF_COLUMN: Readonly<Record<string, LookupName>> = {
|
||||
ItemCode: 'item',
|
||||
WarehouseCode: 'warehouse',
|
||||
FromWarehouseCode: 'warehouse',
|
||||
TaxCode: 'tax',
|
||||
};
|
||||
|
||||
const defaultLookupColumns = (layout: DocumentLayout, name: LookupName): readonly ListColumn[] => {
|
||||
if (layout.lookups?.[name]) return layout.lookups[name]!;
|
||||
if (name === 'partner') return PARTNER_COLUMNS;
|
||||
return layout.columns.find((c) => LOOKUP_OF_COLUMN[c.key] === name)?.lookup?.config.columns ?? [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Cambia las columnas de las listas de valores de un documento. `replace` las sustituye por las
|
||||
* indicadas (el base lo usa); `add` las suma a las que ya tiene (lo usan las extensiones de cliente).
|
||||
* El recurso, el filtro y el orden de cada lista no cambian.
|
||||
*/
|
||||
export function withLookupColumns(layout: DocumentLayout, changes: LookupColumns, mode: 'replace' | 'add'): DocumentLayout {
|
||||
const next: Partial<Record<LookupName, readonly ListColumn[]>> = { ...layout.lookups };
|
||||
for (const name of Object.keys(changes) as LookupName[]) {
|
||||
const given = changes[name] ?? [];
|
||||
next[name] = mode === 'add' ? [...defaultLookupColumns(layout, name), ...given] : given;
|
||||
}
|
||||
const columns = layout.columns.map((c) => {
|
||||
const name = LOOKUP_OF_COLUMN[c.key];
|
||||
const cols = name ? next[name] : undefined;
|
||||
return cols && c.lookup ? { ...c, lookup: { ...c.lookup, config: { ...c.lookup.config, columns: cols } } } : c;
|
||||
});
|
||||
return { ...layout, columns, lookups: next };
|
||||
}
|
||||
|
||||
export const blankLine = (): GridLine => ({ ItemCode: '', ItemDescription: '', Quantity: 1, WarehouseCode: '' });
|
||||
|
||||
// --- documentos con socio de negocio (ventas y compras) -------------------------------------
|
||||
@@ -110,9 +158,11 @@ export function marketingLayout(opts: {
|
||||
right?: readonly HeaderField[];
|
||||
header?: FieldColumns;
|
||||
lineColumns?: readonly GridColumn[];
|
||||
/** Columnas de las listas de valores (cliente, artículo, almacén, impuesto) de este documento. */
|
||||
lookups?: LookupColumns;
|
||||
}): DocumentLayout {
|
||||
const columns = lineColumnsFor(opts.taxResource, opts.lineColumns);
|
||||
return {
|
||||
const layout: DocumentLayout = {
|
||||
lines: { key: 'DocumentLines', fields: lineFieldsOf(columns), base: true },
|
||||
header: opts.header ?? {
|
||||
left: [
|
||||
@@ -139,6 +189,7 @@ export function marketingLayout(opts: {
|
||||
recalc: recalcLine,
|
||||
requiredLine: [],
|
||||
};
|
||||
return opts.lookups ? withLookupColumns(layout, opts.lookups, 'replace') : layout;
|
||||
}
|
||||
|
||||
// --- consultas sobre un layout --------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user