using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging.Abstractions; using Net.Business.Entities; using Net.Business.Entities.ServicesLayer; using Net.Business.Entities.ServicesLayer.CreditNotes; using Net.Business.Entities.ServicesLayer.InventoryGenEntries; using Net.Business.Entities.ServicesLayer.Invoices; using Net.Business.Entities.ServicesLayer.PurchaseDeliveryNotes; using Net.Business.Entities.ServicesLayer.PurchaseInvoices; using Net.Business.Entities.ServicesLayer.PurchaseOrders; using Net.Business.Entities.ServicesLayer.ReturnRequest; using Net.Business.Entities.ServicesLayer.StockTransfer; using Net.Business.Entities.WMS.Recibo; using Net.Connection; using Net.CrossCotting; using Net.Data.HelperData.Stock; using Net.Data.ServicesLayer; using Net.Data.ServicesLayer.CreditNotes; using Net.Data.ServicesLayer.GlobalData; using Net.Data.ServicesLayer.InventoryGenEntries; using Net.Data.ServicesLayer.ReturnRequest; using Net.Data.ServicesLayer.StockTransfer; using Net.Data.WMS.Enums; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Net.Data.WMS.Recibo { public class ReciboRepository : RepositoryBase, IReciboRepository { #region Variables Globales private string _aplicacionName; private string _metodoName; private readonly Regex regex = new Regex(@"<(\w+)>.*"); private readonly IHttpClientFactory _clientFactory; private readonly IConfiguration _configuration; #endregion public ReciboRepository(IConnectionSQL context, IHttpClientFactory clientFactory, IConfiguration configuration) : base(context) { _clientFactory = clientFactory; _configuration = configuration; _aplicacionName = GetType().Name; } public async Task> Create(BE_ReciboRequest entidad) { _metodoName = regex.Match(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name).Groups[1].Value.ToString(); ResultadoTransaccion resultadoTransaccion = new ResultadoTransaccion(_metodoName, _aplicacionName); return await Task.Run(async () => { try { //=== INICIALIZA OBJETO DE SAP PurchaseDeliveryNotesRepository _purchaseDeliveryNotes = new PurchaseDeliveryNotesRepository(_clientFactory, _configuration); CreditNotesRepository _creditNotesRepository = new CreditNotesRepository(_clientFactory, _configuration, context); BusinessPartnersRepository businessPartnersRepository = new BusinessPartnersRepository(_clientFactory, _configuration, context); var response_businessPartnersRepository = await businessPartnersRepository.GetBusinessPartnersByFilter(new FE_BusinessPartners() { CardCode = entidad.CodigoERPProveedor }); if (response_businessPartnersRepository.ListData.Count() == 0) { return resultadoTransaccion.GetInformacionResultado("SAP: El Proveedor no se encuentra registrado en SAP", entidad); } #region PROCESO POR COMPRA DE IMPORTACION if (entidad.IdTipo == EnumRecibo.IMPORTACION) { //=== INICIALIZA OBJETO DE SAP BE_PurchaseDeliveryNotes purchaseDeliveryNotes = new BE_PurchaseDeliveryNotes { DocObjectCode = "oPurchaseDeliveryNotes", DocumentLines = new List() }; if (entidad.IdTipoDoc == EnumRecibo.IMPORTACION_ORDEN) { PurchaseInvoicesRepository purchaseInvoicesRepository = new PurchaseInvoicesRepository(_clientFactory, _configuration); BE_ResultadoTransaccion response_purchaseInvoicesRepository = purchaseInvoicesRepository.GetPurchaseInvoices(entidad.DocEntry).Result; if (response_purchaseInvoicesRepository.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: Factura de reserva por importaciones no se encuentra", entidad); } BE_PurchaseInvoices purchaseOrders = response_purchaseInvoicesRepository.ListData.FirstOrDefault(); purchaseDeliveryNotes.DocCurrency = purchaseOrders.DocCurrency; purchaseDeliveryNotes.CardCode = purchaseOrders.CardCode; purchaseDeliveryNotes.CardName = purchaseOrders.CardName; purchaseDeliveryNotes.PaymentGroupCode = purchaseOrders.PaymentGroupCode; purchaseDeliveryNotes.DocDate = DateTime.Now; purchaseDeliveryNotes.DocDueDate = DateTime.Now; purchaseDeliveryNotes.NumAtCard = entidad.DocImportacion; purchaseDeliveryNotes.U_SYP_MDCD = entidad.U_SYP_MDCD; purchaseDeliveryNotes.U_SYP_MDSD = entidad.U_SYP_MDSD; purchaseDeliveryNotes.U_SYP_MDTD = entidad.U_SYP_MDTD; entidad.Detalle.ForEach(x => { if (x.CantidadPedida > 0) { var Item = purchaseOrders.DocumentLines.ToList().FirstOrDefault(t => t.LineNum == x.Item); if (Item != null) { purchaseDeliveryNotes.DocumentLines.Add(new BE_PurchaseDeliveryNotesLine() { Currency = purchaseOrders.DocCurrency, BatchNumbers = new List { new BE_PurchaseDeliveryNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (int)x.CantidadPedida }, }, ItemCode = Item.ItemCode, ItemDescription = Item.ItemDescription, PriceAfterVAT = Item.PriceAfterVAT, Quantity = (double)x.CantidadPedida, WarehouseCode = Item.WarehouseCode, BaseEntry = entidad.DocEntry, BaseLine = x.Item, BaseType = 18, LineNum = x.Item, }); } } }); var result_purchaseDeliveryNotes = _purchaseDeliveryNotes.SetCreatePurchaseDeliveryNotes(purchaseDeliveryNotes).Result; if (result_purchaseDeliveryNotes.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado(result_purchaseDeliveryNotes.Message, entidad); } return resultadoTransaccion.GetInformacionResultado((int)result_purchaseDeliveryNotes.Data.DocEntry, result_purchaseDeliveryNotes.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); } if (entidad.IdTipoDoc == EnumRecibo.IMPORTACION_ORDEN_COMPRA) { PurchaseOrdersRepository purchaseOrdersRepository = new PurchaseOrdersRepository(_clientFactory, _configuration); BE_ResultadoTransaccion response_purchaseOrdersRepository = purchaseOrdersRepository.GetPurchaseInvoices(entidad.DocEntry).Result; if (response_purchaseOrdersRepository.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: Orden de Compra no se encuentra", entidad); } BE_PurchaseOrders purchaseOrders = response_purchaseOrdersRepository.ListData.FirstOrDefault(); purchaseDeliveryNotes.DocCurrency = purchaseOrders.DocCurrency; purchaseDeliveryNotes.CardCode = purchaseOrders.CardCode; purchaseDeliveryNotes.CardName = purchaseOrders.CardName; purchaseDeliveryNotes.PaymentGroupCode = purchaseOrders.PaymentGroupCode; purchaseDeliveryNotes.DocDate = DateTime.Now; purchaseDeliveryNotes.DocDueDate = DateTime.Now; purchaseDeliveryNotes.NumAtCard = entidad.DocImportacion; purchaseDeliveryNotes.U_SYP_MDCD = entidad.U_SYP_MDCD; purchaseDeliveryNotes.U_SYP_MDSD = entidad.U_SYP_MDSD; purchaseDeliveryNotes.U_SYP_MDTD = entidad.U_SYP_MDTD; entidad.Detalle.ForEach(x => { var Item = purchaseOrders.DocumentLines.ToList().FirstOrDefault(t => t.LineNum == x.Item); if (Item != null) { purchaseDeliveryNotes.DocumentLines.Add(new BE_PurchaseDeliveryNotesLine() { Currency = purchaseOrders.DocCurrency, BatchNumbers = new List { new BE_PurchaseDeliveryNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (int)x.CantidadPedida }, }, ItemCode = Item.ItemCode, ItemDescription = Item.ItemDescription, PriceAfterVAT = Item.PriceAfterVAT, Quantity = (double)x.CantidadPedida, WarehouseCode = Item.WarehouseCode, BaseEntry = entidad.DocEntry, BaseLine = x.Item, BaseType = 22, LineNum = x.Item }); } }); var result_purchaseDeliveryNotes = _purchaseDeliveryNotes.SetCreatePurchaseDeliveryNotes(purchaseDeliveryNotes).Result; if (result_purchaseDeliveryNotes.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado(result_purchaseDeliveryNotes.Message, entidad); } return resultadoTransaccion.GetInformacionResultado((int)result_purchaseDeliveryNotes.Data.DocEntry, result_purchaseDeliveryNotes.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); } if (entidad.IdTipoDoc == EnumRecibo.IMPORTACION_SOL_ENTRADA) { GlobalDataRepository globalDataRepository = new GlobalDataRepository(_clientFactory, _configuration, context); var Result_globalDataRepository = globalDataRepository.GetSolicitudIngreso(entidad.DocEntry).Result.ListData.FirstOrDefault(); BE_InventoryGenEntries _InventoryGenEntries = new BE_InventoryGenEntries() { DocObjectCode = "oInventoryGenEntry", DocDate = DateTime.Now, DocDueDate = DateTime.Now, PaymentGroupCode = "-2", DocCurrency = "S/", DocRate = 1, DocumentLines = new List(), U_SYP_TPOENTME = Result_globalDataRepository.U_ITC_MDTI, U_ITC_WMS_NUMINV = "", U_ARD_PERSOLIC = Result_globalDataRepository.U_ITC_USRSOL, Comments = Result_globalDataRepository.U_ITC_MDCM }; int LineNum = 0; entidad.Detalle.ForEach(detalle => { var LineaDetalle = Result_globalDataRepository.ITC_SOLINGMERDETCollection.FirstOrDefault(x => x.LineId == detalle.Item); var Precio = HelperStock.GetConsolidado(detalle.CodigoArticulo, Result_globalDataRepository.U_ITC_MDWC).FirstOrDefault().AvgPrice; _InventoryGenEntries.DocumentLines.Add(new BE_InventoryGenEntriesLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = LineaDetalle.U_ITC_ITEMNAME, Quantity = (double)detalle.CantidadPedida, LineNum = LineNum, PriceAfterVAT = Precio, LineTotal = Precio * (double)detalle.CantidadPedida, WarehouseCode = Result_globalDataRepository.U_ITC_MDWC, AccountCode = LineaDetalle.U_ITC_ACCCODE, CostingCode = LineaDetalle.U_ITC_CCOSTO ?? "", BatchNumbers = new List() { new BE_InventoryGenEntriesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)detalle.CantidadPedida } } }); LineNum++; }); InventoryGenEntriesRepository inventoryGenEntries = new InventoryGenEntriesRepository(_clientFactory, _configuration, context); var inventoryGenEntries_result = inventoryGenEntries.SetCreateInventoryGenEntries(_InventoryGenEntries, false).Result; if (inventoryGenEntries_result.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(inventoryGenEntries_result.Message.ToString(), entidad); } return resultadoTransaccion.GetInformacionResultado((int)inventoryGenEntries_result.Data.DocEntry, inventoryGenEntries_result.Data.DocNum.ToString(), "Registrado Correctamente", entidad); } } #endregion #region PROCESO POR COMPRA NACIONAL if (entidad.IdTipo == EnumRecibo.NACIONAL) { //=== INICIALIZA OBJETO DE SAP BE_PurchaseDeliveryNotes purchaseDeliveryNotes = new BE_PurchaseDeliveryNotes { DocObjectCode = "oPurchaseDeliveryNotes", DocumentLines = new List() }; PurchaseOrdersRepository purchaseOrdersRepository = new PurchaseOrdersRepository(_clientFactory, _configuration); BE_ResultadoTransaccion response_purchaseOrdersRepository = purchaseOrdersRepository.GetPurchaseInvoices(entidad.DocEntry).Result; if (response_purchaseOrdersRepository.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: Orden de Compra no se encuentra", entidad); } BE_PurchaseOrders purchaseOrders = response_purchaseOrdersRepository.ListData.FirstOrDefault(); purchaseDeliveryNotes.DocCurrency = purchaseOrders.DocCurrency; purchaseDeliveryNotes.CardCode = purchaseOrders.CardCode; purchaseDeliveryNotes.CardName = purchaseOrders.CardName; purchaseDeliveryNotes.PaymentGroupCode = purchaseOrders.PaymentGroupCode; purchaseDeliveryNotes.DocDate = DateTime.Now; purchaseDeliveryNotes.DocDueDate = DateTime.Now; purchaseDeliveryNotes.NumAtCard = entidad.DocImportacion; purchaseDeliveryNotes.U_SYP_MDCD = entidad.U_SYP_MDCD; purchaseDeliveryNotes.U_SYP_MDSD = entidad.U_SYP_MDSD; purchaseDeliveryNotes.U_SYP_MDTD = entidad.U_SYP_MDTD; entidad.Detalle.ForEach(x => { var Item = purchaseOrders.DocumentLines.ToList().FirstOrDefault(t => t.LineNum == x.Item); if (Item != null) { purchaseDeliveryNotes.DocumentLines.Add(new BE_PurchaseDeliveryNotesLine() { Currency = purchaseOrders.DocCurrency, BatchNumbers = new List { new BE_PurchaseDeliveryNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (int)x.CantidadPedida }, }, ItemCode = Item.ItemCode, ItemDescription = Item.ItemDescription, PriceAfterVAT = Item.PriceAfterVAT, Quantity = (double)x.CantidadPedida, WarehouseCode = Item.WarehouseCode, BaseEntry = entidad.DocEntry, BaseLine = x.Item, BaseType = 22, LineNum = x.Item }); } }); var result_purchaseDeliveryNotes = _purchaseDeliveryNotes.SetCreatePurchaseDeliveryNotes(purchaseDeliveryNotes).Result; if (result_purchaseDeliveryNotes.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado(result_purchaseDeliveryNotes.Message, entidad); } return resultadoTransaccion.GetInformacionResultado((int)result_purchaseDeliveryNotes.Data.DocEntry, result_purchaseDeliveryNotes.Data.DocNum.ToString(), "Se registro correctamente...!!!", entidad); } #endregion // DEVOLUCION: NC (oCreditNotes) con base en la Solicitud de Devolucion (BaseType 234000031). // Si las lineas de la solicitud vienen de una factura se usan los datos y lotes de la factura; si no, los de la solicitud y el stock de HANA #region PROCESO DE NOTA DE CREDITO if (entidad.IdTipo == EnumRecibo.DEVOLUCION) { BE_CreditNotesNotes creditNotesNotes = new BE_CreditNotesNotes { DocObjectCode = "oCreditNotes", DocumentLines = new List() }; ReturnRequestRepository returnRequestRepository = new ReturnRequestRepository(_clientFactory, _configuration); BE_ResultadoTransaccion response_purchaseOrdersRepository = returnRequestRepository.GetRequestReturn(entidad.DocEntry).Result; if (response_purchaseOrdersRepository.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: Solicitud de Devolucion no se encuentra", entidad); } BE_ReturnRequest returnRequest = response_purchaseOrdersRepository.ListData.FirstOrDefault(); #region OBTIENE FACTURAS RELACIONADA A LA SOLICITUD DE DEVOLUCION List ListaDocEntryFactura = returnRequest.DocumentLines.Select(x => !x.BaseEntry.HasValue? 0: x.BaseEntry.Value).Distinct().Where(x => x > 0).ToList(); BE_InvoicesConsulta _Invoice = null; ListaDocEntryFactura.ForEach(DocEntry => { var _InvoiceRepository = new InvoiceRepository(_clientFactory, _configuration, context); var _Invoice_Result = _InvoiceRepository.GetInvoice(DocEntry).Result; if (_Invoice_Result.ListData.Count() > 0) { _Invoice = _Invoice_Result.ListData.FirstOrDefault(); } }); string U_SYP_MDTO = ""; string U_SYP_MDCO = ""; string U_SYP_MDSO = ""; DateTime DocDate; if (_Invoice == null) { U_SYP_MDTO = returnRequest.U_SYP_MDTO; U_SYP_MDCO = returnRequest.U_SYP_MDCO; U_SYP_MDSO = returnRequest.U_SYP_MDSO; DocDate = returnRequest.U_SYP_FECHAREF; } else { U_SYP_MDTO = _Invoice.U_SYP_MDTD; U_SYP_MDCO = _Invoice.U_SYP_MDCD; U_SYP_MDSO = _Invoice.U_SYP_MDSD; DocDate = _Invoice.DocDate; } #endregion // Cabecera de la NC: serie BC10/FC10 por el TIPO del documento origen (v2.1.7.0), correlativo y documento origen. // El origen es la factura de la solicitud de devolucion o, si no hay, la propia solicitud CabeceraNotaCredito.Completar(creditNotesNotes, returnRequest.DocCurrency, returnRequest.CardCode, returnRequest.CardName, returnRequest.PaymentGroupCode, U_SYP_MDTO, U_SYP_MDSO, U_SYP_MDCO, DocDate, returnRequest.U_SYP_MOTNC, returnRequest.U_SYP_TPONC); entidad.Detalle.ForEach(x => { var Item = returnRequest.DocumentLines.ToList().FirstOrDefault(t => t.LineNum == x.Item); if (Item != null) { creditNotesNotes.DocumentLines.Add(new BE_CreditNotesLine() { Currency = returnRequest.DocCurrency, BatchNumbers = new List { new BE_CreditNotesBatchNumbers() { BatchNumber = x.LoteProducto, Quantity = (int)x.CantidadPedida }, }, ItemCode = Item.ItemCode, ItemDescription = Item.ItemDescription, PriceAfterVAT = Item.PriceAfterVAT, Quantity = x.CantidadPedida, WarehouseCode = Item.WarehouseCode, BaseEntry = entidad.DocEntry, BaseLine = x.Item, BaseType = 234000031, LineNum = x.Item }); } }); // Lotes de cada linea: sin factura relacionada, FIFO por vencimiento del stock de HANA; con factura, los lotes de la factura. // En ambos casos se parte de la lista vacia para que los lotes sumen exactamente la cantidad de la linea if (_Invoice == null) { //=== REALIZA DISTRIBUCION DE STOCK POR LOTE creditNotesNotes.DocumentLines.ForEach(line => { // La linea nace con un lote del request (LoteProducto); se descarta para que // los lotes finales sean solo los de la distribucion y sumen la cantidad de la linea line.BatchNumbers.Clear(); #region CONSULTA A HANA var ListaStock = HelperStock.Get(line.ItemCode, line.WarehouseCode); if (ListaStock.Count > 0) { var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock.OrderBy(x => x.ExpDate).ToList(); ListOrdenadaFecha.ForEach(Lote => { if (CantidadPendiente > 0) { if (Lote.OnHandQty >= (double)CantidadPendiente) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = (double)CantidadPendiente }); CantidadPendiente = 0; } else if (Lote.OnHandQty < (double)CantidadPendiente) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = (double)Lote.OnHandQty }); CantidadPendiente -= (decimal)Lote.OnHandQty; } } }); // Stock de HANA menor a la cantidad: el resto va a un lote nuevo para que los lotes sumen la cantidad de la linea if (CantidadPendiente > 0) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)CantidadPendiente }); } } else { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)line.Quantity }); } #endregion }); } else { creditNotesNotes.DocumentLines.ForEach(line => { line.BatchNumbers.Clear(); var ReferenciaFactura = returnRequest.DocumentLines.FirstOrDefault(t => t.LineNum == line.LineNum); var ListaStock = _Invoice.DocumentLines.FirstOrDefault(InvoiceLine => InvoiceLine.LineNum == ReferenciaFactura.BaseLine)?.BatchNumbers ?? new List(); if (ListaStock.Count > 0) { var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock; ListOrdenadaFecha.ForEach(Lote => { if (CantidadPendiente > 0) { if (Lote.Quantity >= (double)CantidadPendiente) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = Lote.BatchNumber, Quantity = (double)CantidadPendiente }); CantidadPendiente = 0; } else if (Lote.Quantity < (double)CantidadPendiente) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = Lote.BatchNumber, Quantity = (double)Lote.Quantity }); CantidadPendiente -= (decimal)Lote.Quantity; } } }); // Lotes de la factura menores a la cantidad: el resto va a un lote nuevo para que los lotes sumen la cantidad de la linea if (CantidadPendiente > 0) { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)CantidadPendiente }); } } else { line.BatchNumbers.Add(new BE_CreditNotesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)line.Quantity }); } }); } var result_creditNotesRepository = _creditNotesRepository.SetCreateCreditNotes(creditNotesNotes).Result; if (result_creditNotesRepository.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado(result_creditNotesRepository.Message, entidad); } else { // 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 var advertenciaTransferencias = 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...!!!" + advertenciaTransferencias, entidad); } } #endregion return resultadoTransaccion.GetInformacionResultado(0, "", "Se registro correctamente...!!!", entidad); } catch (Exception ex) { return resultadoTransaccion.GetInformacionResultado(ex.Message.ToString(), entidad); } }); } } }