From 2182147adbbc23b81c99f239c0422eeee770f4ad Mon Sep 17 00:00:00 2001 From: george Date: Mon, 19 Oct 2026 15:40:19 -0500 Subject: [PATCH] =?UTF-8?q?Versi=C3=B3n=202.0.0:=20validar=20contra=20Cons?= =?UTF-8?q?ignaci=C3=B3n=20(suma=20de=20OpenInvQty)=20en=20lugar=20del=20s?= =?UTF-8?q?tock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DP_Stock (v2) suma PDN1.OpenInvQty de las Entradas de Consignación abiertas del almacén, lo mismo que usa el FIFO. La columna se muestra como Consignación. Co-Authored-By: Claude Sonnet 5.5 --- .../planificaciones.service.ts | 2 +- .../sql-queries/sql-queries.definitions.ts | 25 +++++++++++++------ .../planificaciones/detalle/detalle.html | 2 +- .../pages/planificaciones/detalle/detalle.ts | 2 +- .../pages/planificaciones/nueva/nueva.html | 6 ++--- .../pages/planificaciones/nueva/nueva.spec.ts | 2 +- .../app/pages/planificaciones/nueva/nueva.ts | 2 +- libs/shared/src/domain/fifo.spec.ts | 4 +-- libs/shared/src/domain/fifo.ts | 2 +- package-lock.json | 4 +-- package.json | 2 +- 11 files changed, 32 insertions(+), 21 deletions(-) diff --git a/apps/api/src/planificaciones/planificaciones.service.ts b/apps/api/src/planificaciones/planificaciones.service.ts index bc0eec1..f798657 100644 --- a/apps/api/src/planificaciones/planificaciones.service.ts +++ b/apps/api/src/planificaciones/planificaciones.service.ts @@ -107,7 +107,7 @@ export class PlanificacionesService { for (const { fila, stock } of consultas) { if (!stock) { - errores.push(`${fila.itemCode}: el artículo no existe o no tiene stock registrado en el almacén ${whsCode}.`); + errores.push(`${fila.itemCode}: el artículo no existe.`); continue; } const articulo: ArticuloADevolver = { diff --git a/apps/api/src/sql-queries/sql-queries.definitions.ts b/apps/api/src/sql-queries/sql-queries.definitions.ts index 8d65d44..2990621 100644 --- a/apps/api/src/sql-queries/sql-queries.definitions.ts +++ b/apps/api/src/sql-queries/sql-queries.definitions.ts @@ -15,17 +15,28 @@ export interface ConsultaGuardada { hana: string; } +/** + * "Stock" = lo que realmente se puede devolver: la suma de PDN1.OpenInvQty de las líneas abiertas de + * Entradas de mercancías de Consignación (U_DOT_TipoRecepcion = 'C') del almacén, las mismas que usa el + * FIFO. No es OITW.OnHand: el stock físico incluye mercancía que no es devolvible por esta vía. + * Devuelve fila (con 0) si el artículo existe pero no tiene consignación; ninguna si no existe. + * La columna se sigue llamando OnHand porque así se guarda en el UDO (U_OnHand). + */ export const CONSULTA_STOCK: ConsultaGuardada = { codigo: 'DP_Stock', - version: 1, + version: 2, mssql: - 'SELECT T0.[ItemCode], T0.[ItemName], T1.[OnHand] ' + - 'FROM OITM T0 INNER JOIN OITW T1 ON T1.[ItemCode] = T0.[ItemCode] ' + - 'WHERE T1.[WhsCode] = :whs AND T0.[ItemCode] = :item', + 'SELECT T0.[ItemCode], T0.[ItemName], ' + + 'COALESCE((SELECT SUM(T2.[OpenInvQty]) FROM OPDN T1 INNER JOIN PDN1 T2 ON T2.[DocEntry] = T1.[DocEntry] ' + + "WHERE T1.[U_DOT_TipoRecepcion] = 'C' AND T2.[LineStatus] = 'O' " + + 'AND T2.[ItemCode] = T0.[ItemCode] AND T2.[WhsCode] = :whs), 0) AS [OnHand] ' + + 'FROM OITM T0 WHERE T0.[ItemCode] = :item', hana: - 'SELECT T0."ItemCode", T0."ItemName", T1."OnHand" ' + - 'FROM OITM T0 INNER JOIN OITW T1 ON T1."ItemCode" = T0."ItemCode" ' + - 'WHERE T1."WhsCode" = :whs AND T0."ItemCode" = :item', + 'SELECT T0."ItemCode", T0."ItemName", ' + + 'COALESCE((SELECT SUM(T2."OpenInvQty") FROM OPDN T1 INNER JOIN PDN1 T2 ON T2."DocEntry" = T1."DocEntry" ' + + "WHERE T1.\"U_DOT_TipoRecepcion\" = 'C' AND T2.\"LineStatus\" = 'O' " + + 'AND T2."ItemCode" = T0."ItemCode" AND T2."WhsCode" = :whs), 0) AS "OnHand" ' + + 'FROM OITM T0 WHERE T0."ItemCode" = :item', }; /** diff --git a/apps/web/src/app/pages/planificaciones/detalle/detalle.html b/apps/web/src/app/pages/planificaciones/detalle/detalle.html index 95372f5..7cce6c9 100644 --- a/apps/web/src/app/pages/planificaciones/detalle/detalle.html +++ b/apps/web/src/app/pages/planificaciones/detalle/detalle.html @@ -136,7 +136,7 @@ - + diff --git a/apps/web/src/app/pages/planificaciones/detalle/detalle.ts b/apps/web/src/app/pages/planificaciones/detalle/detalle.ts index 3c4eb76..6a78a66 100644 --- a/apps/web/src/app/pages/planificaciones/detalle/detalle.ts +++ b/apps/web/src/app/pages/planificaciones/detalle/detalle.ts @@ -260,7 +260,7 @@ export class PlanificacionDetallePage implements OnInit, OnDestroy { { titulo: 'Artículo', ancho: 18 }, { titulo: 'Descripción', ancho: 45 }, { titulo: 'Cantidad', tipo: 'numero' }, - { titulo: 'Stock', tipo: 'numero' }, + { titulo: 'Consignación', tipo: 'numero' }, { titulo: 'Estado', ancho: 11 }, { titulo: 'Devolver', ancho: 10 }, { titulo: 'Entrada', tipo: 'numero' }, diff --git a/apps/web/src/app/pages/planificaciones/nueva/nueva.html b/apps/web/src/app/pages/planificaciones/nueva/nueva.html index 8e21079..426dccb 100644 --- a/apps/web/src/app/pages/planificaciones/nueva/nueva.html +++ b/apps/web/src/app/pages/planificaciones/nueva/nueva.html @@ -1,7 +1,7 @@

{{ reemplaza() ? 'Rehacer planificación Nº ' + reemplazaNumero() : 'Nueva planificación' }}

-

Pegue los artículos y cantidades desde Excel; se valida el stock del almacén antes de procesar.

+

Pegue los artículos y cantidades desde Excel; se valida contra lo disponible en Consignación del almacén (cantidad abierta de las Entradas de mercancías) antes de procesar.

Volver
@@ -91,7 +91,7 @@
ArtículoCantidadStockArtículoCantidadConsignación EntradaFecha entradaAbiertaAsignada ProveedorDevolución
- + @@ -112,7 +112,7 @@
CódigoDescripciónA devolverStockEstadoCódigoDescripciónA devolverConsignaciónEstado
@if (sinStock() > 0) {

- {{ sinStock() }} artículo(s) sin stock suficiente quedarán fuera al procesar. + {{ sinStock() }} artículo(s) sin consignación suficiente quedarán fuera al procesar.

} diff --git a/apps/web/src/app/pages/planificaciones/nueva/nueva.spec.ts b/apps/web/src/app/pages/planificaciones/nueva/nueva.spec.ts index c3a9a5e..78bb099 100644 --- a/apps/web/src/app/pages/planificaciones/nueva/nueva.spec.ts +++ b/apps/web/src/app/pages/planificaciones/nueva/nueva.spec.ts @@ -95,7 +95,7 @@ describe('NuevaPlanificacionPage', () => { expect(nombres[0]).toMatch(/^articulos-validados-01-\d{4}-\d{2}-\d{2}\.xlsx$/); const hoja = leerZip(new Uint8Array(await blobs[0].arrayBuffer())).get('xl/worksheets/sheet1.xml')!; expect(filasDeHoja(hoja)).toEqual([ - ['Código', 'Descripción', 'A devolver', 'Stock', 'Estado'], + ['Código', 'Descripción', 'A devolver', 'Consignación', 'Estado'], ['A1', 'Libro', '5', '10', 'OK'], ['A2', 'Libro', '5', '10', 'Sin stock'], ]); diff --git a/apps/web/src/app/pages/planificaciones/nueva/nueva.ts b/apps/web/src/app/pages/planificaciones/nueva/nueva.ts index 397c804..d128e5d 100644 --- a/apps/web/src/app/pages/planificaciones/nueva/nueva.ts +++ b/apps/web/src/app/pages/planificaciones/nueva/nueva.ts @@ -154,7 +154,7 @@ export class NuevaPlanificacionPage implements OnInit { { titulo: 'Código', ancho: 18 }, { titulo: 'Descripción', ancho: 50 }, { titulo: 'A devolver', tipo: 'numero', ancho: 12 }, - { titulo: 'Stock', tipo: 'numero', ancho: 12 }, + { titulo: 'Consignación', tipo: 'numero', ancho: 12 }, { titulo: 'Estado', ancho: 12 }, ], filas: lineas.map((l) => [l.itemCode, l.itemDescription, l.quantity, l.onHand, l.status === 'OK' ? 'OK' : 'Sin stock']), diff --git a/libs/shared/src/domain/fifo.spec.ts b/libs/shared/src/domain/fifo.spec.ts index 9d54fc6..45b4425 100644 --- a/libs/shared/src/domain/fifo.spec.ts +++ b/libs/shared/src/domain/fifo.spec.ts @@ -20,10 +20,10 @@ describe('asignarFifo', () => { expect(lineas[1]).toMatchObject({ itemCode: 'a001', applied: true, baseType: 20, baseRef: 1001 }); }); - it('omite artículos sin stock suficiente', () => { + it('omite artículos sin consignación suficiente', () => { const { lineas, advertencias } = asignarFifo([{ itemCode: 'A001', itemName: 'Art', quantity: 6, onHand: 5 }], new Map()); expect(lineas).toEqual([]); - expect(advertencias[0]).toContain('sin stock'); + expect(advertencias[0]).toContain('sin consignación'); }); it('advierte cuando las Entradas no alcanzan', () => { diff --git a/libs/shared/src/domain/fifo.ts b/libs/shared/src/domain/fifo.ts index 7346198..a980ef7 100644 --- a/libs/shared/src/domain/fifo.ts +++ b/libs/shared/src/domain/fifo.ts @@ -76,7 +76,7 @@ export function asignarFifo(articulos: ArticuloADevolver[], entradasPorItem: Map const padre = crearLineaPadre(articulo); if (padre.status === 'SIN_STOCK') { - advertencias.push(`${articulo.itemCode}: sin stock suficiente (${articulo.onHand} de ${articulo.quantity}), se omite.`); + advertencias.push(`${articulo.itemCode}: sin consignación suficiente (${articulo.onHand} de ${articulo.quantity}), se omite.`); continue; } diff --git a/package-lock.json b/package-lock.json index 7bfb317..851538b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "devolucion-proveedores-web", - "version": "1.1.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "devolucion-proveedores-web", - "version": "1.1.0", + "version": "2.0.0", "workspaces": [ "libs/*", "apps/*" diff --git a/package.json b/package.json index f06a5dc..740a8bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "devolucion-proveedores-web", - "version": "1.1.0", + "version": "2.0.0", "private": true, "workspaces": [ "libs/*",