import type { GridLine } from '../../shared/grid/grid.types'; import type { DocRecord } from './document-model'; import { newDocumentLine, recalcLine } from './line-columns'; /** Tipo de objeto de SAP de cada documento (`BaseType` de las líneas copiadas). */ export const OBJECT_TYPES: Readonly> = { '/ventas/ofertas': 23, '/ventas/ordenes': 17, '/ventas/entrega': 15, '/ventas/devoluciones': 16, '/ventas/facturas': 13, '/ventas/notas-credito': 14, '/compras/ofertas': 540000006, '/compras/ordenes': 22, '/compras/recepcion': 20, '/compras/devoluciones': 21, '/compras/facturas': 18, '/compras/notas-credito': 19, }; /** De qué documento se puede copiar a cuáles (el flujo estándar de SAP B1). */ export const COPY_FLOWS: Readonly> = { '/ventas/ofertas': ['/ventas/ordenes', '/ventas/entrega', '/ventas/facturas'], '/ventas/ordenes': ['/ventas/entrega', '/ventas/facturas'], '/ventas/entrega': ['/ventas/facturas', '/ventas/devoluciones'], '/ventas/devoluciones': ['/ventas/notas-credito'], '/ventas/facturas': ['/ventas/notas-credito'], '/compras/ofertas': ['/compras/ordenes'], '/compras/ordenes': ['/compras/recepcion', '/compras/facturas'], '/compras/recepcion': ['/compras/facturas', '/compras/devoluciones'], '/compras/devoluciones': ['/compras/notas-credito'], '/compras/facturas': ['/compras/notas-credito'], }; /** Documentos a los que se puede copiar desde `path` ("Copiar a"). */ export const copyTargets = (path: string): readonly string[] => COPY_FLOWS[path] ?? []; /** Documentos desde los que se puede copiar a `path` ("Copiar de"). */ export const copySources = (path: string): readonly string[] => Object.entries(COPY_FLOWS) .filter(([, to]) => to.includes(path)) .map(([from]) => from); /** Origen de un copiado, enviado en el estado de la navegación hacia el documento nuevo. */ export interface CopyOrigin { path: string; docEntry: number; } export interface CopiedDocument { header: DocRecord; lines: GridLine[]; /** Líneas del origen que no se copian porque ya están cerradas. */ skipped: number; } /** * Datos de un documento origen para uno nuevo: socio y referencias, y sus líneas abiertas con la * cantidad pendiente y la referencia al origen (`BaseType`/`BaseEntry`/`BaseLine`), con lo que SAP * enlaza y cierra las cantidades del origen. */ export function copyFromDocument(source: DocRecord, sourcePath: string, sourceLabel: string): CopiedDocument { const baseType = OBJECT_TYPES[sourcePath]; const lines: GridLine[] = []; let skipped = 0; for (const l of (source['DocumentLines'] as GridLine[] | undefined) ?? []) { const remaining = Number(l['RemainingOpenQuantity'] ?? l['Quantity'] ?? 0); if (l['LineStatus'] === 'bost_Close' || !(remaining > 0)) { skipped++; continue; } lines.push( recalcLine({ ...newDocumentLine(), ItemCode: l['ItemCode'] ?? '', ItemDescription: l['ItemDescription'] ?? '', Quantity: remaining, WarehouseCode: l['WarehouseCode'] ?? '', Price: l['Price'] ?? null, DiscountPercent: l['DiscountPercent'] ?? 0, TaxCode: l['TaxCode'] ?? '', BaseType: baseType, BaseEntry: source['DocEntry'], BaseLine: l['LineNum'], }), ); } return { header: { CardCode: source['CardCode'] ?? '', NumAtCard: source['NumAtCard'] ?? '', DiscountPercent: source['DiscountPercent'] ?? 0, Comments: `Basado en ${sourceLabel.toLowerCase()} ${String(source['DocNum'])}.`, }, lines, skipped, }; }