using iTextSharp.text; using Microsoft.Extensions.Configuration; using Net.Business.Entities; using Net.Business.Entities.ServicesLayer; using Net.Business.Entities.ServicesLayer.Invoices; using Net.Business.Entities.ServicesLayer.Items; using Net.Business.Entities.ServicesLayer.PurchaseDeliveryNotes; using Net.Business.Entities.ServicesLayer.StockTransfer; using Net.Business.Entities.WMS.Transferencia; using Net.Connection; using Net.CrossCotting; using Net.Data.HelperData.Invoices; using Net.Data.HelperData.Stock; using Net.Data.ServicesLayer; using Net.Data.ServicesLayer.StockTransfer; using Sap.Data.Hana; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Net.Data.WMS.Transferencia { public class TransferenciaRepository : RepositoryBase, ITransferenciaRepository { #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 TransferenciaRepository(IConnectionSQL context, IHttpClientFactory clientFactory, IConfiguration configuration) : base(context) { _clientFactory = clientFactory; _configuration = configuration; _aplicacionName = GetType().Name; } public async Task> Create(BE_TransferenciaRequest entidad) { _metodoName = regex.Match(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name).Groups[1].Value.ToString(); ResultadoTransaccion resultadoTransaccion = new ResultadoTransaccion(_metodoName, _aplicacionName); return await Task.Run(() => { try { //=== CREA INSTANCIA PARA CONECTAR A SAP StockTransferRepository stockTransferRepository = new StockTransferRepository(_clientFactory, _configuration); BE_StockTransfer StockTransfer = new BE_StockTransfer { DocDate = entidad.FechaOrden, DueDate = entidad.FechaOrden, TaxDate = entidad.FechaOrden, FromWarehouse = entidad.CodigoSubAlmacenOrigen, ToWarehouse = entidad.CodigoSubAlmacenDestino, Comments = "Transferencia Generado desde Cubico - SAP", StockTransferLines = new List() }; entidad.TransferenciaDetalles.ForEach(x => { var Detalle = new BE_StockTransferLine { FromWarehouseCode = entidad.CodigoSubAlmacenOrigen, WarehouseCode = entidad.CodigoSubAlmacenDestino, ItemCode = x.CodigoArticulo, Quantity = (double)x.CantidadPedida, BaseLine = entidad.DocEntry == 0 ? null : (int?)x.Item, BaseEntry = entidad.DocEntry == 0 ? null : (int?)entidad.DocEntry, BaseType = entidad.DocEntry == 0 ? null : "InventoryTransferRequest", LineNum = x.Item, BatchNumbers = new List() }; StockTransfer.StockTransferLines.Add(Detalle); }); // == REALIZA DISTRIBUCION DE STOCK POR LOTE / ALMACEN StockTransfer.StockTransferLines.ForEach(line => { #region CONSULTA A HANA List ListaStock = HelperStock.Get(line.ItemCode, line.FromWarehouseCode); var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock.OrderBy(x => x.ExpDate).ToList(); ListOrdenadaFecha.ForEach(Lote => { if (CantidadPendiente > 0) { if (Lote.OnHandQty >= CantidadPendiente) { line.BatchNumbers.Add(new BE_StockTransferLineBatchNumber() { BatchNumber = Lote.DistNumber, Quantity = CantidadPendiente }); CantidadPendiente = 0; } else if (Lote.OnHandQty < CantidadPendiente) { line.BatchNumbers.Add(new BE_StockTransferLineBatchNumber() { BatchNumber = Lote.DistNumber, Quantity = Lote.OnHandQty }); CantidadPendiente -= Lote.OnHandQty; } } }); #endregion }); //=== SI EL ALMACEN ES ALM99 (almacen de costeo de importaciones), AMARRA CON LA ENTRADA DE MERCANCIA if (entidad.CodigoSubAlmacenOrigen == "ALM99") { StockTransfer.U_SYP_MDMT = "21"; PurchaseDeliveryNotesRepository _purchaseDeliveryNotesRepository = new PurchaseDeliveryNotesRepository(_clientFactory, _configuration); if (entidad.DocEntryEM > 0) { // WMS indica la entrada: se toman sus lotes y se amarra linea por linea (BaseLine del JSON == BaseLine de la entrada) var pdn = _purchaseDeliveryNotesRepository.GetPurchaseDeliveryNotes(entidad.DocEntryEM).Result.ListData?.FirstOrDefault(); if (pdn == null) { return resultadoTransaccion.GetInformacionResultado($"SAP: La entrada de mercaderia {entidad.DocEntryEM} no se encuentra", entidad); } foreach (var line in StockTransfer.StockTransferLines) { var Lines = pdn.DocumentLines.FirstOrDefault(l => l.BaseLine == line.LineNum); if (Lines == null) { return resultadoTransaccion.GetInformacionResultado($"SAP: La linea {line.LineNum} no existe en la entrada de mercaderia {entidad.DocEntryEM}", entidad); } line.BatchNumbers = (Lines.BatchNumbers ?? new List()) .Select(lotes => new BE_StockTransferLineBatchNumber() { BatchNumber = lotes.BatchNumber, Quantity = lotes.Quantity }).ToList(); line.BaseLine = Lines.LineNum; line.BaseType = "PurchaseDeliveryNotes"; line.BaseEntry = entidad.DocEntryEM; } } else { // WMS envia en NumOrden el DocNum de la Factura de Reserva y en el detalle los articulos/cantidades de UNA de sus // entradas: se busca la entrada con ese mismo juego que aun no tenga transferencia y se transfiere esa. var filas = HelperInvoice.GetEntradasPorFactura(entidad.NumOrden); if (filas.Count > 0) { int docEntryEntrada = EntradaImportacion.Elegir(entidad.NumOrden, filas, entidad.TransferenciaDetalles, out string errorEntrada); if (docEntryEntrada == 0) { return resultadoTransaccion.GetInformacionResultado(errorEntrada, entidad); } var pdn = _purchaseDeliveryNotesRepository.GetPurchaseDeliveryNotes(docEntryEntrada).Result.ListData?.FirstOrDefault(); if (pdn == null) { return resultadoTransaccion.GetInformacionResultado($"SAP: La entrada de mercaderia {docEntryEntrada} no se puede leer", entidad); } // Las lineas de la transferencia salen de la entrada (articulo, cantidad y lotes reales de cada linea) StockTransfer.StockTransferLines = new List(); foreach (var l in pdn.DocumentLines) { var lotes = (l.BatchNumbers ?? new List()) .Select(b => new BE_StockTransferLineBatchNumber() { BatchNumber = b.BatchNumber, Quantity = b.Quantity }).ToList(); if (lotes.Count > 0 && Math.Abs(lotes.Sum(b => b.Quantity) - l.Quantity) > 0.0001) { return resultadoTransaccion.GetInformacionResultado($"SAP: Los lotes de la linea {l.LineNum} ({l.ItemCode}) de la entrada {docEntryEntrada} no cubren la cantidad {l.Quantity}", entidad); } StockTransfer.StockTransferLines.Add(new BE_StockTransferLine { FromWarehouseCode = entidad.CodigoSubAlmacenOrigen, WarehouseCode = entidad.CodigoSubAlmacenDestino, ItemCode = l.ItemCode, Quantity = l.Quantity, LineNum = l.LineNum, BaseType = "PurchaseDeliveryNotes", BaseEntry = docEntryEntrada, BaseLine = l.LineNum, BatchNumbers = lotes }); } } // Si la factura no tiene entradas (o NumOrden no es una factura de reserva) se mantiene lo de antes: // transferencia con los lotes del stock de HANA, sin amarre. } } var ResultTransaction = stockTransferRepository.StockTransfer(StockTransfer).Result; if (ResultTransaction.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(ResultTransaction.Message.ToString(), entidad); } // === SOLO SE EJECUTA CUANDO TIENE UN DOCUMENTO BASE [SOLICITUD DE TRASLADO] if (entidad.DocEntry != 0) { var Result_SolicitudTraslado = stockTransferRepository.GetInventoryTransferRequest(entidad.DocEntry).Result; if (Result_SolicitudTraslado.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: La solicitud no se encuentra", entidad); } var _SolicitudTraslado = Result_SolicitudTraslado.ListData.FirstOrDefault(); // === SOLO CIERRA CUANDO EL DOCUMENTO ESTA ABIERTO if (_SolicitudTraslado.DocumentStatus == "bost_Open") { var Response_Close = stockTransferRepository.CloseInventoryTransferRequest(entidad.DocEntry).Result; if (Response_Close.DocEntry == -1) { return resultadoTransaccion.GetInformacionResultado("SAP: La Solicitud no se puede cerrar en automatico", entidad); } } } return resultadoTransaccion.GetInformacionResultado((int)ResultTransaction.Data.DocEntry, ResultTransaction.Data.DocNum.ToString(), "Registrado Correctamente", entidad); } catch (Exception ex) { return resultadoTransaccion.GetInformacionResultado(ex.Message.ToString(), entidad); } }); } } }