6.9 KiB
Transferencia de stock desde ALM99 (importaciones) — v2.1.9.0
Documento de soporte. Código: Net.Data/WMS/Transferencia/TransferenciaRepository.cs (bloque ALM99),
Net.Data/WMS/Transferencia/EntradaImportacion.cs (elección de la entrada) y
Net.Data/HelperData/Invoices/HelperInvoice.GetEntradasPorFactura (consulta HANA).
Endpoint: POST /api/Transferencia.
Proceso de negocio
- En SAP se crea una Factura de Reserva de proveedores y se envía al WMS para su recepción.
- El WMS recibe por partes: por cada recepción crea una Entrada de Mercadería
(
PurchaseDeliveryNotes) enlazada a la factura (BaseType 18,BaseEntry,BaseLine). Hay una o varias entradas por factura y todas ingresan al almacén ALM99 (costeo). El WMS no guarda elDocEntryde las entradas, solo sabe qué artículos recibió en cada una. - En SAP se hace el costeo (precio de entrega) de las entradas.
- Terminado el costeo, el WMS notifica una transferencia por entrada hacia el almacén final.
JSON que envía el WMS
numorden= DocNum de la factura de reserva (único).codigoSubAlmacenOrigen=ALM99;codigoSubAlmacenDestino= almacén final (p. ej.ALM21).docEntry= 0 (no hay solicitud de traslado);docEntryEMno se envía.detalle= los artículos y cantidades de una sola entrada. Solo se usancodigoarticuloycantidadpedida;itemyloteproductose ignoran en este caso.
Qué hace la API (origen = ALM99 y sin docEntryEM)
- Consulta HANA (
HelperInvoice.GetEntradasPorFactura): facturaOPCHconDocNum = numordenyisIns = 'Y'(= factura de reserva) → líneasPDN1conBaseType 18yBaseEntry= factura → entradaOPDNno anulada (CANCELED = 'N'). - Una entrada ya tiene transferencia si la línea tiene
TargetType = 67y suTrgetEntryapunta a una transferenciaOWTRconCANCELED = 'N'. Una transferencia anulada libera la entrada. EntradaImportacion.Elegircompara, por entrada, el conjuntoItemCode→ cantidad (sumada por artículo) contra el detalle del JSON (también sumado). Debe coincidir exacto (mismos artículos, mismas cantidades, tolerancia 0.0001). Se toma la entrada más antigua (menorDocEntry) que coincida y no tenga transferencia.- Se lee la entrada por Service Layer (
PurchaseDeliveryNotes(docEntry)) y las líneas de la transferencia salen de la entrada: artículo, cantidad, lotes reales y base (BaseType "PurchaseDeliveryNotes",BaseEntry,BaseLine= línea de la entrada). Si los lotes de una línea no suman su cantidad, responde error antes de enviar a SAP. - Se envía
StockTransfersconU_SYP_MDMT = "21".
Respuestas de error (400, mensaje en la respuesta y en ITCA_LOG_INTEGRACION)
| Mensaje | Causa |
|---|---|
SAP: Ninguna entrada de la factura de reserva X coincide con los articulos y cantidades enviados. Entradas pendientes de transferir (DocNum): ... |
El JSON no es igual a ninguna entrada (falta/sobra un artículo o cambia una cantidad). Lista las entradas aún sin transferir para comparar. |
SAP: Todas las entradas de la factura de reserva X con esos articulos y cantidades ya estan transferidas: entrada N ya transferida en la transferencia M |
Reintento del mismo JSON o entrada ya transferida (evita duplicados). |
SAP: Los lotes de la linea L (item) de la entrada N no cubren la cantidad Q |
La entrada tiene lotes que no suman la cantidad de la línea. |
SAP: La entrada de mercaderia N no se puede leer |
Falló el GET al Service Layer. |
Error de SAP al crear StockTransfers |
Ver la fila PROCESO='ServiceLayer Error' (JSON enviado + mensaje de SAP). |
Otros casos del mismo endpoint (no cambiaron)
- Transferencia simple (origen distinto de ALM99,
docEntry = 0): lotes por stock HANA (FEFO), sin base. - Con solicitud de traslado (
docEntry ≠ 0): la solicitud es la base y se cierra al terminar. - ALM99 con
docEntryEMinformado: se respeta; lotes y base de esa entrada, amarrandoBaseLinedel JSON conBaseLinede la entrada. Si la entrada o la línea no existen responde error claro. - ALM99 cuando la factura no tiene entradas (o
numordenno es una factura de reserva): se mantiene el comportamiento anterior (lotes del stock de HANA, sin amarre).
Verificado y pendiente
- Verificado con datos reales (SQL Server): la consulta encuentra las entradas por
BaseType 18yisIns='Y'; muestra el estado de transferencia por línea (entradas con 1 y con 2 líneas) y una transferencia cancelada vuelve a dejar la entrada libre (TransferenciaDocEntry = 0). - Verificado con simulación: la lógica de
Elegir(coincidencia, entrada más antigua, ya transferida, no coincide). - Pendiente de confirmar contra SAP/HANA reales: que la consulta corra en HANA (la API usa HANA);
que SAP acepte
BaseType "PurchaseDeliveryNotes"en las líneas deStockTransfers; y el caso en que una entrada de varias líneas tenga transferida solo una línea (hoy cuenta como ya transferida).
Cómo diagnosticar ("no se genera la transferencia")
- Ver la fila en
"ITC_WMS_SAP"."ITCA_LOG_INTEGRACION"conPROCESO = 'Transferencia'yNRO_ORDEN = <numorden>: trae el JSON del WMS y la respuesta (el mensaje de la tabla de arriba). - Ejecutar la consulta de
HelperInvoice.GetEntradasPorFactura(versión SQL Server/HANA al final) con elDocNum: si no devuelve filas, la factura no existe, no es de reserva (isIns) o sus entradas no tienenBaseType 18; siTransferenciaDocEntry ≠ 0, esa entrada ya fue transferida. - Comparar artículos y cantidades del JSON contra las filas de esa entrada.
-- HANA (reemplazar <ESQUEMA> y el DocNum de la factura de reserva)
SELECT E."DocEntry", E."DocNum", L."LineNum", L."ItemCode", L."Quantity",
CASE WHEN L."TargetType" = 67 AND W."DocEntry" IS NOT NULL AND W."CANCELED" = 'N'
THEN W."DocEntry" ELSE 0 END AS "TransferenciaDocEntry"
FROM "<ESQUEMA>"."OPCH" F
INNER JOIN "<ESQUEMA>"."PDN1" L ON L."BaseType" = 18 AND L."BaseEntry" = F."DocEntry"
INNER JOIN "<ESQUEMA>"."OPDN" E ON E."DocEntry" = L."DocEntry"
LEFT JOIN "<ESQUEMA>"."OWTR" W ON L."TargetType" = 67 AND W."DocEntry" = L."TrgetEntry"
WHERE F."DocNum" = 262000082 AND F."isIns" = 'Y' AND E."CANCELED" = 'N'
ORDER BY E."DocEntry", L."LineNum";
En SQL Server es la misma consulta sin comillas dobles y con [<BASE>].dbo.OPCH, etc.
Historia
Antes (también en el código del desarrollador anterior y en el commit inicial) el bloque dependía de
DocEntryEM, que el WMS no envía: nunca se amarraba a la entrada y los lotes salían solo del stock de HANA
(sin validar que cubrieran la cantidad). La versión original buscaba la entrada por NumOrden con
HelperInvoice.Get (procedimiento ITCA_WMS_SAP_GetEntradaPorImportacion, un solo DocEntry), que quedó
comentado; no servía para varias entradas por factura. Esa función sigue en el código sin llamadores.