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); }