From 3ea0aca5351ad705e5ac5eafee87efd1881d7f98 Mon Sep 17 00:00:00 2001 From: George Date: Wed, 14 Oct 2026 19:52:53 -0500 Subject: [PATCH] Unificar la transferencia automatica de la NC en TransferenciaAutomaticaNC.Crear El mismo bloque (~100 lineas) estaba copiado en Picking DESPACHO, Picking PICKING y Recibo. Ahora los tres llaman al mismo metodo. Sin cambios de comportamiento (la referencia de la NC en la transferencia se asigna una vez antes de las lineas en vez de dentro del ciclo de articulos). Co-Authored-By: Claude Sonnet 5.5 --- CLAUDE.md | 10 +- .../TransferenciaAutomaticaNC.cs | 114 ++++++++++ Net.Data/WMS/Picking/PickingRepository.cs | 202 +----------------- Net.Data/WMS/Recibo/ReciboRepository.cs | 99 +-------- 4 files changed, 126 insertions(+), 299 deletions(-) create mode 100644 Net.Data/ServicesLayer/StockTransfer/TransferenciaAutomaticaNC.cs diff --git a/CLAUDE.md b/CLAUDE.md index 6f0c095..bdd4473 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,8 +98,9 @@ transferencias siempre, sin depender de `Notificacion`. Detalle y tabla en exactas sin llamadores: `HelperHojaRuta.GetConsolidado` (queda `HelperStock.GetConsolidado`) y `HRRepository.UpdateCreateCreditNotes` (queda `CreditNotesRepository`). Sigue pendiente: código comentado, `PatchAsyncSBA`, repositorios de compras sin uso - (`SetCreatePurchaseInvoices` duplicado en `PurchaseOrdersRepository`) y la redundancia de las transferencias automáticas - (3 copias en Picking/Recibo) y de los métodos POST/PATCH del cliente. + (`SetCreatePurchaseInvoices` duplicado en `PurchaseOrdersRepository`) y la redundancia de los métodos POST/PATCH del cliente. + La transferencia automática de stock de la NC (3 copias en Picking x2 y Recibo) + pasó a un solo método: `Net.Data/ServicesLayer/StockTransfer/TransferenciaAutomaticaNC.Crear`. - Sin probar contra SAP: confirmar con la factura 292410 que SAP devuelve `BaseType`/`BaseEntry` en las líneas y `BatchNumbers` en las de la Entrega. @@ -164,9 +165,8 @@ Picking, columna `HORA` en `B_Log`. Lo que **no** se trajo: `Chatbots` y `ITC_WMS_SAP` (`ITCA_LOG_INTEGRACION`), no en `LocalData.Schema`; si la tabla está en otro esquema el `INSERT` falla. `B_Log.Add` no tiene `try/catch`, así que un fallo del log puede devolver 500 tras haber creado el documento en SAP. -- En Picking y Recibo, si la transferencia automática de stock falla, el `if` - de error está vacío: el fallo se ignora (la NC ya está creada) y no se informa - al consumidor. +- Si una transferencia automática de stock falla (`TransferenciaAutomaticaNC.Crear`), + el fallo se ignora (la NC ya está creada) y no se informa al consumidor. ## Despliegue diff --git a/Net.Data/ServicesLayer/StockTransfer/TransferenciaAutomaticaNC.cs b/Net.Data/ServicesLayer/StockTransfer/TransferenciaAutomaticaNC.cs new file mode 100644 index 0000000..becfe4b --- /dev/null +++ b/Net.Data/ServicesLayer/StockTransfer/TransferenciaAutomaticaNC.cs @@ -0,0 +1,114 @@ +using Microsoft.Extensions.Configuration; +using Net.Business.Entities.ServicesLayer.CreditNotes; +using Net.Business.Entities.ServicesLayer.StockTransfer; +using Net.Data.ServicesLayer.CreditNotes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; + +namespace Net.Data.ServicesLayer.StockTransfer +{ + // Transferencias de stock automaticas de una nota de credito (Picking DESPACHO/PICKING y Recibo Devolucion). + // Antes este bloque estaba copiado 3 veces. + public static class TransferenciaAutomaticaNC + { + // Por cada almacen de origen (WarehouseCode) y almacen destino (U_ITC_ALMDES) distintos de las lineas de la NC + // crea una transferencia de stock en SAP, con las cantidades y lotes de esas lineas y la NC como referencia. + // Luego agrega a la NC una referencia por cada transferencia creada. + // OJO: si SAP rechaza una transferencia se ignora (la NC ya esta creada) y no se informa al consumidor. + public static void Crear(BE_CreditNotesNotes creditNotesNotes, int docEntryNC, IHttpClientFactory clientFactory, IConfiguration configuration, CreditNotesRepository creditNotesRepository) + { + List ListaUnicaAlmacen = creditNotesNotes.DocumentLines.Select(x => x.WarehouseCode).Distinct().ToList(); + List ListDocEntry = new List(); + ListaUnicaAlmacen.ForEach(Almacen => + { + List ListaUnicaAlmDestino = creditNotesNotes.DocumentLines.Where(Linea => Linea.WarehouseCode == Almacen).ToList().Select(x => x.U_ITC_ALMDES).Distinct().ToList().Where(x => !string.IsNullOrEmpty(x)).ToList(); + ListaUnicaAlmDestino.ForEach(Destino => + { + if (Almacen != Destino) + { + BE_StockTransferAutomatico Transfer = new BE_StockTransferAutomatico(); + Transfer.FromWarehouse = Almacen; + Transfer.ToWarehouse = Destino; + Transfer.DocDate = creditNotesNotes.DocDate; + Transfer.TaxDate = creditNotesNotes.DocDate; + Transfer.U_SYP_MDTS = "TSI"; + Transfer.U_SYP_MDMT = "24"; + Transfer.DueDate = creditNotesNotes.DocDueDate; + Transfer.PriceList = -2; + var ListaDetalle_PorAlmacen = creditNotesNotes.DocumentLines.Where(x => x.WarehouseCode == Almacen && x.U_ITC_ALMDES == Destino).ToList(); + var ListaUnicaArticulo = ListaDetalle_PorAlmacen.Select(x => x.ItemCode).Distinct().ToList(); + Transfer.StockTransferLines = new List(); + + //=== AGREGA DOCUMENTO REFERENCIA + Transfer.DocumentReferences = new List + { + new BE_StockTransferDocumentReferences() + { + RefDocEntr = docEntryNC, + RefObjType = "rot_SalesCreditNote", + IssueDate = DateTime.Now, + Remark = "Nota de Credito", + } + }; + + ListaUnicaArticulo.ForEach(x => + { + var ListLote = new List(); + // Lotes de todas las lineas del articulo (si el mismo lote esta en varias lineas se suma) + ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).SelectMany(t => t.BatchNumbers).GroupBy(r => r.BatchNumber).ToList().ForEach(g => + { + ListLote.Add(new BE_StockTransferLineBatchNumber() + { + BatchNumber = g.Key, + Quantity = g.Sum(r => r.Quantity) + }); + }); + Transfer.StockTransferLines.Add(new BE_StockTransferLine() + { + ItemCode = x, + ItemDescription = ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).FirstOrDefault().ItemDescription, + Quantity = Convert.ToDouble(ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).Sum(t => t.Quantity)), + WarehouseCode = Destino, + FromWarehouseCode = Almacen, + BatchNumbers = ListLote + }); + }); + + //=== CREA INSTANCIA PARA CONECTAR A SAP + StockTransferRepository stockTransferRepository = new StockTransferRepository(clientFactory, configuration); + var ResultTransfer = stockTransferRepository.StockTransfer(Transfer).Result; + if (ResultTransfer.StatusCode != -1) + { + ListDocEntry.Add((int)ResultTransfer.Data.DocEntry); + } + } + }); + }); + + // Referencia las transferencias creadas en la NC + if (ListDocEntry.Count > 0) + { + var listaReferencia = new List(); + ListDocEntry.ForEach(x => + { + listaReferencia.Add(new BE_CreditNotesDocumentReferences() + { + RefDocEntr = x, + IssueDate = DateTime.Now, + RefObjType = "rot_InventoryTransfer", + Remark = "Transferencias Automatica" + }); + }); + + var credit = new + { + DocumentReferences = listaReferencia + }; + + var Actualizacion = creditNotesRepository.UpdateCreateCreditNotes(credit, docEntryNC).Result; + } + } + } +} diff --git a/Net.Data/WMS/Picking/PickingRepository.cs b/Net.Data/WMS/Picking/PickingRepository.cs index 9598afc..ad451a3 100644 --- a/Net.Data/WMS/Picking/PickingRepository.cs +++ b/Net.Data/WMS/Picking/PickingRepository.cs @@ -299,108 +299,8 @@ namespace Net.Data.WMS.Picking } else { - // Por cada almacen de origen y almacen destino (U_ITC_ALMDES) distintos se crea una transferencia de stock automatica - List ListaUnicaAlmacen = creditNotesNotes.DocumentLines.Select(x => x.WarehouseCode).Distinct().ToList(); - List ListDocEntry = new List(); - ListaUnicaAlmacen.ForEach(Almacen => - { - List ListaUnicaAlmDestino = creditNotesNotes.DocumentLines.Where(Linea => Linea.WarehouseCode == Almacen).ToList().Select(x => x.U_ITC_ALMDES).Distinct().ToList().Where(x => !string.IsNullOrEmpty(x)).ToList(); - ListaUnicaAlmDestino.ForEach(Destino => - { - if (Almacen != Destino) - { - BE_StockTransferAutomatico Transfer = new BE_StockTransferAutomatico(); - Transfer.FromWarehouse = Almacen; - Transfer.ToWarehouse = Destino; - Transfer.DocDate = creditNotesNotes.DocDate; - Transfer.TaxDate = creditNotesNotes.DocDate; - Transfer.U_SYP_MDTS = "TSI"; - Transfer.U_SYP_MDMT = "24"; - Transfer.DueDate = creditNotesNotes.DocDueDate; - Transfer.PriceList = -2; - var ListaDetalle_PorAlmacen = creditNotesNotes.DocumentLines.Where(x => x.WarehouseCode == Almacen && x.U_ITC_ALMDES == Destino).ToList(); - var ListaUnicaArticulo = ListaDetalle_PorAlmacen.Select(x => x.ItemCode).Distinct().ToList(); - Transfer.StockTransferLines = new List(); - Transfer.DocumentReferences = new List(); - ListaUnicaArticulo.ForEach(x => - { - var ListLote = new List(); - // Lotes de todas las lineas del articulo (si el mismo lote esta en varias lineas se suma) - ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).SelectMany(t => t.BatchNumbers).GroupBy(r => r.BatchNumber).ToList().ForEach(g => - { - ListLote.Add(new BE_StockTransferLineBatchNumber() - { - BatchNumber = g.Key, - Quantity = g.Sum(r => r.Quantity) - }); - }); - Transfer.StockTransferLines.Add(new BE_StockTransferLine() - { - - ItemCode = x, - ItemDescription = ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).FirstOrDefault().ItemDescription, - Quantity = Convert.ToDouble(ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).Sum(t => t.Quantity)), - WarehouseCode = Destino, - FromWarehouseCode = Almacen, - BatchNumbers = ListLote - }); - - - //=== AGREGA DOCUMENTO REFERENCIA - Transfer.DocumentReferences = new List - { - new BE_StockTransferDocumentReferences() - { - RefDocEntr = (int)result_creditNotesRepository.Data.DocEntry, - RefObjType = "rot_SalesCreditNote", - IssueDate = DateTime.Now, - Remark = "Nota de Credito", - } - }; - - - - }); - - //=== CREA INSTANCIA PARA CONECTAR A SAP - StockTransferRepository stockTransferRepository = new StockTransferRepository(_clientFactory, _configuration); - var ResultTransfer = stockTransferRepository.StockTransfer(Transfer).Result; - // OJO: si la transferencia falla se ignora (la NC ya esta creada) y no se informa al consumidor - if (ResultTransfer.StatusCode == -1) - { - - } - else - { - ListDocEntry.Add((int)ResultTransfer.Data.DocEntry); - } - } - }); - }); - - - // Referencia las transferencias creadas en la NC - if (ListDocEntry.Count > 0) - { - var listaReferencia = new List(); - ListDocEntry.ForEach(x => - { - listaReferencia.Add(new BE_CreditNotesDocumentReferences() - { - RefDocEntr = x, - IssueDate = DateTime.Now, - RefObjType = "rot_InventoryTransfer", - Remark = "Transferencias Automatica" - }); - }); - - var credit = new - { - DocumentReferences = listaReferencia - }; - - var Actualizacion = _creditNotesRepository.UpdateCreateCreditNotes(credit, (int)result_creditNotesRepository.Data.DocEntry).Result; - } + // Transferencias de stock automaticas por almacen destino (U_ITC_ALMDES) y su referencia en la NC + TransferenciaAutomaticaNC.Crear(creditNotesNotes, (int)result_creditNotesRepository.Data.DocEntry, _clientFactory, _configuration, _creditNotesRepository); return resultadoTransaccion.GetInformacionResultado((int)result_creditNotesRepository.Data.DocEntry, result_creditNotesRepository.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); } } @@ -598,102 +498,8 @@ namespace Net.Data.WMS.Picking else { - // Transferencias automaticas por almacen origen/destino (igual que en DESPACHO) - List ListaUnicaAlmacen = creditNotesNotes.DocumentLines.Select(x => x.WarehouseCode).Distinct().ToList(); - List ListDocEntry = new List(); - ListaUnicaAlmacen.ForEach(Almacen => - { - List ListaUnicaAlmDestino = creditNotesNotes.DocumentLines.Where(Linea => Linea.WarehouseCode == Almacen).ToList().Select(x => x.U_ITC_ALMDES).Distinct().ToList().Where(x => !string.IsNullOrEmpty(x)).ToList(); - ListaUnicaAlmDestino.ForEach(Destino => - { - if (Almacen != Destino) - { - BE_StockTransferAutomatico Transfer = new BE_StockTransferAutomatico(); - Transfer.FromWarehouse = Almacen; - Transfer.ToWarehouse = Destino; - Transfer.DocDate = creditNotesNotes.DocDate; - Transfer.TaxDate = creditNotesNotes.DocDate; - Transfer.DueDate = creditNotesNotes.DocDueDate; - Transfer.U_SYP_MDTS = "TSI"; - Transfer.U_SYP_MDMT = "24"; - Transfer.PriceList = -2; - var ListaDetalle_PorAlmacen = creditNotesNotes.DocumentLines.Where(x => x.WarehouseCode == Almacen && x.U_ITC_ALMDES == Destino).ToList(); - var ListaUnicaArticulo = ListaDetalle_PorAlmacen.Select(x => x.ItemCode).Distinct().ToList(); - - Transfer.StockTransferLines = new List(); - Transfer.DocumentReferences = new List(); - - ListaUnicaArticulo.ForEach(x => - { - var ListLote = new List(); - // Lotes de todas las lineas del articulo (si el mismo lote esta en varias lineas se suma) - ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).SelectMany(t => t.BatchNumbers).GroupBy(r => r.BatchNumber).ToList().ForEach(g => - { - ListLote.Add(new BE_StockTransferLineBatchNumber() - { - BatchNumber = g.Key, - Quantity = g.Sum(r => r.Quantity) - }); - }); - Transfer.StockTransferLines.Add(new BE_StockTransferLine() - { - ItemCode = x, - ItemDescription = ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).FirstOrDefault().ItemDescription, - Quantity = Convert.ToDouble(ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).Sum(t => t.Quantity)), - WarehouseCode = Destino, - FromWarehouseCode = Almacen, - BatchNumbers = ListLote - }); - - //=== AGREGA DOCUMENTO REFERENCIA - Transfer.DocumentReferences = new List - { - new BE_StockTransferDocumentReferences() - { - RefDocEntr = (int)result_creditNotesRepository.Data.DocEntry, - RefObjType = "rot_SalesCreditNote", - IssueDate = DateTime.Now, - Remark = "Nota de Credito", - } - }; - }); - - //=== CREA INSTANCIA PARA CONECTAR A SAP - StockTransferRepository stockTransferRepository = new StockTransferRepository(_clientFactory, _configuration); - var ResultTransfer = stockTransferRepository.StockTransfer(Transfer).Result; - // OJO: si la transferencia falla se ignora (la NC ya esta creada) - if (ResultTransfer.StatusCode == -1) - { - - } - else - { - ListDocEntry.Add((int)ResultTransfer.Data.DocEntry); - } - } - }); - }); - - if (ListDocEntry.Count > 0) - { - var listaReferencia = new List(); - ListDocEntry.ForEach(x => - { - listaReferencia.Add(new BE_CreditNotesDocumentReferences() - { - RefDocEntr = x, - IssueDate = DateTime.Now, - RefObjType = "rot_InventoryTransfer", - Remark = "Transferencias Automatica" - }); - }); - - var credit = new - { - DocumentReferences = listaReferencia - }; - var Actualizacion = _creditNotesRepository.UpdateCreateCreditNotes(credit, (int)result_creditNotesRepository.Data.DocEntry).Result; - } + // Transferencias de stock automaticas por almacen destino (U_ITC_ALMDES) y su referencia en la NC + TransferenciaAutomaticaNC.Crear(creditNotesNotes, (int)result_creditNotesRepository.Data.DocEntry, _clientFactory, _configuration, _creditNotesRepository); return resultadoTransaccion.GetInformacionResultado((int)result_creditNotesRepository.Data.DocEntry, result_creditNotesRepository.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); } } diff --git a/Net.Data/WMS/Recibo/ReciboRepository.cs b/Net.Data/WMS/Recibo/ReciboRepository.cs index 8afbafe..65964c0 100644 --- a/Net.Data/WMS/Recibo/ReciboRepository.cs +++ b/Net.Data/WMS/Recibo/ReciboRepository.cs @@ -537,102 +537,9 @@ namespace Net.Data.WMS.Recibo } else { - // Transferencias por almacen destino (U_ITC_ALMDES). OJO: en Recibo las lineas de la NC no llenan U_ITC_ALMDES, por lo que hoy no se genera ninguna - List ListaUnicaAlmacen = creditNotesNotes.DocumentLines.Select(x => x.WarehouseCode).Distinct().ToList(); - List ListDocEntry = new List(); - ListaUnicaAlmacen.ForEach(Almacen => - { - List ListaUnicaAlmDestino = creditNotesNotes.DocumentLines.Where(Linea => Linea.WarehouseCode == Almacen).ToList().Select(x => x.U_ITC_ALMDES).Distinct().ToList().Where(x => !string.IsNullOrEmpty(x)).ToList(); - ListaUnicaAlmDestino.ForEach(Destino => - { - if (Almacen != Destino) - { - BE_StockTransferAutomatico Transfer = new BE_StockTransferAutomatico(); - Transfer.FromWarehouse = Almacen; - Transfer.ToWarehouse = Destino; - Transfer.DocDate = creditNotesNotes.DocDate; - Transfer.TaxDate = creditNotesNotes.DocDate; - Transfer.DueDate = creditNotesNotes.DocDueDate; - Transfer.U_SYP_MDTS = "TSI"; - Transfer.U_SYP_MDMT = "24"; - Transfer.PriceList = -2; - var ListaDetalle_PorAlmacen = creditNotesNotes.DocumentLines.Where(x => x.WarehouseCode == Almacen && x.U_ITC_ALMDES == Destino).ToList(); - var ListaUnicaArticulo = ListaDetalle_PorAlmacen.Select(x => x.ItemCode).Distinct().ToList(); - - Transfer.StockTransferLines = new List(); - Transfer.DocumentReferences = new List(); - - ListaUnicaArticulo.ForEach(x => - { - var ListLote = new List(); - // Lotes de todas las lineas del articulo (si el mismo lote esta en varias lineas se suma) - ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).SelectMany(t => t.BatchNumbers).GroupBy(r => r.BatchNumber).ToList().ForEach(g => - { - ListLote.Add(new BE_StockTransferLineBatchNumber() - { - BatchNumber = g.Key, - Quantity = g.Sum(r => r.Quantity) - }); - }); - Transfer.StockTransferLines.Add(new BE_StockTransferLine() - { - ItemCode = x, - ItemDescription = ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).FirstOrDefault().ItemDescription, - Quantity = Convert.ToDouble(ListaDetalle_PorAlmacen.Where(t => t.ItemCode == x).Sum(t => t.Quantity)), - WarehouseCode = Destino, - FromWarehouseCode = Almacen, - BatchNumbers = ListLote - }); - - //=== AGREGA DOCUMENTO REFERENCIA - Transfer.DocumentReferences = new List - { - new BE_StockTransferDocumentReferences() - { - RefDocEntr = (int)result_creditNotesRepository.Data.DocEntry, - RefObjType = "rot_SalesCreditNote", - IssueDate = DateTime.Now, - Remark = "Nota de Credito", - } - }; - }); - - //=== CREA INSTANCIA PARA CONECTAR A SAP - StockTransferRepository stockTransferRepository = new StockTransferRepository(_clientFactory, _configuration); - var ResultTransfer = stockTransferRepository.StockTransfer(Transfer).Result; - // OJO: si la transferencia falla se ignora (la NC ya esta creada) - if (ResultTransfer.StatusCode == -1) - { - - } - else - { - ListDocEntry.Add((int)ResultTransfer.Data.DocEntry); - } - } - }); - }); - - if (ListDocEntry.Count > 0) - { - var listaReferencia = new List(); - ListDocEntry.ForEach(x => - { - listaReferencia.Add(new BE_CreditNotesDocumentReferences() - { - RefDocEntr = x, - IssueDate = DateTime.Now, - RefObjType = "rot_InventoryTransfer", - Remark = "Transferencias Automatica" - }); - }); - - var credit = new - { - DocumentReferences = listaReferencia - }; - var Actualizacion = _creditNotesRepository.UpdateCreateCreditNotes(credit, (int)result_creditNotesRepository.Data.DocEntry).Result; - } + // Transferencias de stock automaticas por almacen destino (U_ITC_ALMDES). OJO: en Recibo las lineas de la NC no llenan + // U_ITC_ALMDES, por lo que hoy no se genera ninguna + TransferenciaAutomaticaNC.Crear(creditNotesNotes, (int)result_creditNotesRepository.Data.DocEntry, _clientFactory, _configuration, _creditNotesRepository); return resultadoTransaccion.GetInformacionResultado((int)result_creditNotesRepository.Data.DocEntry, result_creditNotesRepository.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); }