feat(web): fila del flete (gastos adicionales) y toolbar de ancho completo; la configuración de pantallas se carga en diferido
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d3ab97cd2e
commit
d6c127627f
14 files changed
+360
-27
No files matched your search
@@ -20,7 +20,12 @@ export function isDocumentReadOnly(doc: DocRecord | null | undefined): boolean {
|
||||
|
||||
// --- totales ------------------------------------------------------------------------------
|
||||
|
||||
/** Gasto adicional del documento (el flete): colección `DocumentAdditionalExpenses` de SAP. */
|
||||
export const FREIGHT_COLLECTION = 'DocumentAdditionalExpenses';
|
||||
|
||||
export interface DocTotals {
|
||||
/** Flete (gastos adicionales) antes de impuestos. */
|
||||
freight: number;
|
||||
/** Suma de los totales de línea (ya con el descuento de cada línea). */
|
||||
subtotal: number;
|
||||
/** Descuento del documento (% de cabecera aplicado al subtotal). */
|
||||
@@ -44,6 +49,7 @@ export function computeTotals(
|
||||
lines: readonly GridLine[],
|
||||
rates: ReadonlyMap<string, number>,
|
||||
discountPercent: number,
|
||||
freight = 0,
|
||||
): DocTotals {
|
||||
const factor = 1 - discountPercent / 100;
|
||||
let subtotal = 0;
|
||||
@@ -59,10 +65,50 @@ export function computeTotals(
|
||||
discount: round2(subtotal - net),
|
||||
net: round2(net),
|
||||
tax: round2(tax),
|
||||
total: round2(net + tax),
|
||||
freight: round2(freight),
|
||||
total: round2(net + tax + freight),
|
||||
};
|
||||
}
|
||||
|
||||
// --- flete ---------------------------------------------------------------------------------
|
||||
|
||||
/** Flete del documento tal como se edita: el código del gasto y el importe (`FreightExpense`, `FreightAmount`). */
|
||||
export function freightOf(doc: DocRecord | undefined): { expense: string; amount: number; editable: boolean } {
|
||||
const rows = (doc?.[FREIGHT_COLLECTION] as DocRecord[] | undefined) ?? [];
|
||||
return {
|
||||
expense: rows[0]?.['ExpenseCode'] === undefined || rows[0]?.['ExpenseCode'] === null ? '' : String(rows[0]['ExpenseCode']),
|
||||
amount: round2(rows.reduce((sum, r) => sum + num(r['LineTotal']), 0)),
|
||||
// con varios gastos adicionales (cargados en SAP) el flete solo se muestra: no se puede reducir a una fila
|
||||
editable: rows.length <= 1,
|
||||
};
|
||||
}
|
||||
|
||||
const FREIGHT_KEYS = ['FreightExpense', 'FreightAmount'] as const;
|
||||
const withoutFreight = (r: DocRecord): DocRecord => Object.fromEntries(Object.entries(r).filter(([k]) => !(FREIGHT_KEYS as readonly string[]).includes(k)));
|
||||
|
||||
/**
|
||||
* Convierte los campos del flete del formulario (`FreightExpense`, `FreightAmount`) en la colección
|
||||
* `DocumentAdditionalExpenses` que espera SAP. `expense` es el código elegido o, si no eligió, el
|
||||
* de flete por defecto. Al crear, sin importe no se envía nada; al modificar solo si cambió (con
|
||||
* `replace`, porque SAP reemplaza la colección entera) y un importe 0 quita el flete.
|
||||
*/
|
||||
export function freightPayload(
|
||||
body: DocRecord,
|
||||
header: DocRecord,
|
||||
expense: string,
|
||||
mode: 'create' | 'update',
|
||||
hadFreight = false,
|
||||
): { body: DocRecord; replace: boolean } {
|
||||
const touched = FREIGHT_KEYS.some((k) => k in body);
|
||||
if (mode === 'update' && !touched) return { body, replace: false };
|
||||
const amount = round2(num(header['FreightAmount']));
|
||||
const code = isEmpty(header['FreightExpense']) ? expense : String(header['FreightExpense']);
|
||||
const rest = withoutFreight(body);
|
||||
if (amount > 0 && code !== '') return { body: { ...rest, [FREIGHT_COLLECTION]: [{ ExpenseCode: Number(code), LineTotal: amount }] }, replace: true };
|
||||
if (mode === 'update' && hadFreight) return { body: { ...rest, [FREIGHT_COLLECTION]: [] }, replace: true };
|
||||
return { body: rest, replace: false };
|
||||
}
|
||||
|
||||
// --- guardado -----------------------------------------------------------------------------
|
||||
|
||||
/** Campos de línea que se envían a SAP; el total de línea y lo calculado lo resuelve SAP. */
|
||||
|
||||
Reference in new issue
Block a user