using Microsoft.Extensions.Configuration; using Net.Business.Entities; using Net.Business.Entities.ServicesLayer.InventoryGenEntries; using Net.Business.Entities.ServicesLayer.InventoryGenExits; using Net.Business.Entities.ServicesLayer.Items; using Net.Business.Entities.ServicesLayer.StockTransfer; using Net.Business.Entities.WMS.Inventario; using Net.Connection; using Net.CrossCotting; using Net.Data.HelperData; using Net.Data.HelperData.Inventario; using Net.Data.HelperData.Stock; using Net.Data.ServicesLayer.InventoryGenEntries; using Net.Data.ServicesLayer.InventoryGenExits; using Net.Data.ServicesLayer.StockTransfer; 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.Inventario { public class InventarioRepository : RepositoryBase, IInventarioRepository { #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 InventarioRepository(IConnectionSQL context, IHttpClientFactory clientFactory, IConfiguration configuration) : base(context) { _clientFactory = clientFactory; _configuration = configuration; _aplicacionName = GetType().Name; } public async Task> Create(BE_Inventario entidad) { _metodoName = regex.Match(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name).Groups[1].Value.ToString(); ResultadoTransaccion resultadoTransaccion = new ResultadoTransaccion(_metodoName, _aplicacionName); if (string.IsNullOrEmpty(entidad.TipoMovimiento)) { return resultadoTransaccion.GetInformacionResultado("El campo Tipo Movimiento no puede ser vacio", entidad); } if (string.IsNullOrEmpty(entidad.TipoMovimientoSAP)) { return resultadoTransaccion.GetInformacionResultado("El campo Tipo Movimiento SAP no puede ser vacio", entidad); } if (string.IsNullOrEmpty(entidad.TipoInventario)) { return resultadoTransaccion.GetInformacionResultado("El campo Tipo Inventario no puede ser vacio", entidad); } //=== ASIGNA PRECIO PROMEDIO (solo aplica a entradas de mercancia) if (entidad.TipoMovimiento == "01") { foreach (var x in entidad.Detalle) { var Stock = HelperStock.GetConsolidado(x.CodigoArticulo, entidad.SubAlmacen); // Un ingreso puede crear el primer stock del articulo: sin datos se conserva el precio del request if (Stock.Count > 0) { x.PrecioPromedio = Stock.FirstOrDefault().AvgPrice; } }; } var ListaxLista = new List(); var lista = entidad.Detalle; for (int i = 0; i < lista.Count; i += 100) { var bloque = lista.Skip(i).Take(100).ToList(); // Copia por bloque: antes se reutilizaba "entidad" y todos los bloques // terminaban apuntando al ultimo detalle (documentos repetidos y lineas perdidas) var Inventario = new BE_Inventario() { Fecha = entidad.Fecha, FechaVencimiento = entidad.FechaVencimiento, TipoMovimientoSAP = entidad.TipoMovimientoSAP, TipoMovimiento = entidad.TipoMovimiento, TipoInventario = entidad.TipoInventario, Almacen = entidad.Almacen, SubAlmacen = entidad.SubAlmacen, NroInventario = entidad.NroInventario, Detalle = bloque }; ListaxLista.Add(Inventario); } return await Task.Run(() => { try { string CuentaContable = HelperInventario.Get(entidad.TipoMovimientoSAP); if (string.IsNullOrEmpty(CuentaContable)) { return resultadoTransaccion.GetInformacionResultado("No existe cuenta contable configurado para el tipo movimiento SAP", entidad); } //=== OBTIENE PRECIO PROMEDIO (solo aplica a entradas de mercancia) if (entidad.TipoMovimiento == "01") { entidad.Detalle.ForEach(detalle => { var ListaStockConsolidado = HelperStock.GetConsolidado(detalle.CodigoArticulo, entidad.Almacen); // Un ingreso puede crear el primer stock del articulo: sin datos se conserva el precio del request if (ListaStockConsolidado.Count > 0) { detalle.PrecioPromedio = ListaStockConsolidado.FirstOrDefault().AvgPrice; } }); } //=== TIPO DE INVENTARIO GENERAL if (entidad.TipoInventario == "01") { //=== INGRESO DE MERCANCIA if (entidad.TipoMovimiento == "01") { int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { 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 = entidad_inventario.TipoMovimientoSAP, U_ITC_WMS_NUMINV = entidad_inventario.NroInventario }; int LineNum = 0; entidad_inventario.Detalle.ForEach(detalle => { _InventoryGenEntries.DocumentLines.Add(new BE_InventoryGenEntriesLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = detalle.DescripcionArticulo, Quantity = (double)detalle.Cantidad, LineNum = LineNum, PriceAfterVAT = detalle.PrecioPromedio, LineTotal = detalle.PrecioPromedio * (double)detalle.Cantidad, WarehouseCode = entidad.SubAlmacen, AccountCode = CuentaContable, CostingCode = detalle.CentroCosto ?? "", BatchNumbers = new List() { new BE_InventoryGenEntriesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)detalle.Cantidad } } }); 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); } DocEntry = (int)inventoryGenEntries_result.Data.DocEntry; DocNum = (int)inventoryGenEntries_result.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); } //=== SALIDA DE MERCANCIA if (entidad.TipoMovimiento == "02") { int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { BE_InventoryGenExits _InventoryGenExits = new BE_InventoryGenExits() { DocObjectCode = "oInventoryGenExit", DocDate = DateTime.Now, DocDueDate = DateTime.Now, PaymentGroupCode = "-2", DocCurrency = "S/", DocRate = 1, DocumentLines = new List(), U_SYP_TPOSALME = entidad_inventario.TipoMovimientoSAP, U_ITC_WMS_NUMINV = entidad_inventario.NroInventario }; int LineNum = 0; entidad_inventario.Detalle.ForEach(detalle => { _InventoryGenExits.DocumentLines.Add(new BE_InventoryGenExitsLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = detalle.DescripcionArticulo, Quantity = (double)detalle.Cantidad, LineNum = LineNum, PriceAfterVAT = detalle.PrecioPromedio, LineTotal = detalle.PrecioPromedio * (double)detalle.Cantidad, WarehouseCode = entidad.SubAlmacen, AccountCode = CuentaContable, BatchNumbers = new List(), CostingCode = detalle.CentroCosto ?? "", }); LineNum++; }); _InventoryGenExits.DocumentLines.ForEach(line => { #region CONSULTA A HANA List ListaStock = HelperStock.Get(line.ItemCode, entidad.SubAlmacen); var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock.OrderBy(x => x.ExpDate).ToList(); var cantidadStock = ListaStock.Sum(x => x.OnHandQty); if (cantidadStock < line.Quantity) { throw new Exception($"El producto {line.ItemCode} no cuenta con stock suficiente"); } else { ListOrdenadaFecha.ForEach(Lote => { if (CantidadPendiente > 0) { if (Lote.OnHandQty >= CantidadPendiente) { line.BatchNumbers.Add(new BE_InventoryGenExitsBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = CantidadPendiente }); CantidadPendiente = 0; } else if (Lote.OnHandQty < CantidadPendiente) { line.BatchNumbers.Add(new BE_InventoryGenExitsBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = Lote.OnHandQty }); CantidadPendiente -= Lote.OnHandQty; } } }); } #endregion }); InventoryGenExitsRepository inventoryGenExits = new InventoryGenExitsRepository(_clientFactory, _configuration, context); var inventoryGenExits_result = inventoryGenExits.SetCreateInventoryGenExits(_InventoryGenExits, false).Result; if (inventoryGenExits_result.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(inventoryGenExits_result.Message.ToString(), entidad); } DocEntry = (int)inventoryGenExits_result.Data.DocEntry; DocNum = (int)inventoryGenExits_result.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); } } //=== TIPO DE INVENTARIO CICLICO if (entidad.TipoInventario == "02") { //=== INGRESO DE MERCANCIA if (entidad.TipoMovimiento == "01") { int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { 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 = entidad_inventario.TipoMovimientoSAP, U_ITC_WMS_NUMINV = entidad_inventario.NroInventario }; int LineNum = 0; entidad_inventario.Detalle.ForEach(detalle => { _InventoryGenEntries.DocumentLines.Add(new BE_InventoryGenEntriesLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = detalle.DescripcionArticulo, Quantity = (double)detalle.Cantidad, LineNum = LineNum, PriceAfterVAT = detalle.PrecioPromedio, LineTotal = detalle.PrecioPromedio * (double)detalle.Cantidad, WarehouseCode = entidad.SubAlmacen, AccountCode = CuentaContable, CostingCode = detalle.CentroCosto ?? "", BatchNumbers = new List() { new BE_InventoryGenEntriesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)detalle.Cantidad } } }); LineNum++; }); InventoryGenEntriesRepository inventoryGenEntries = new InventoryGenEntriesRepository(_clientFactory, _configuration, context); var inventoryGenEntries_result = inventoryGenEntries.SetCreateInventoryGenEntries(_InventoryGenEntries).Result; if (inventoryGenEntries_result.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(inventoryGenEntries_result.Message.ToString(), entidad); } DocEntry = (int)inventoryGenEntries_result.Data.DocEntry; DocNum = (int)inventoryGenEntries_result.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); } //=== SALIDA DE MERCANCIA [GENERA TRANSFERENCIA] if (entidad.TipoMovimiento == "02") { string AlmacenDestino = "ALM12"; //=== CREA INSTANCIA PARA CONECTAR A SAP StockTransferRepository stockTransferRepository = new StockTransferRepository(_clientFactory, _configuration); int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { BE_StockTransfer StockTransfer = new BE_StockTransfer { DocDate = DateTime.Now, DueDate = DateTime.Now, TaxDate = DateTime.Now, FromWarehouse = entidad.SubAlmacen, ToWarehouse = AlmacenDestino, Comments = "Transferencia Generado desde Cubico - SAP", StockTransferLines = new List(), U_ITC_WMS_NUMINV = entidad.NroInventario, U_SYP_TPOENTME = entidad.TipoMovimientoSAP }; int LineNum = 0; entidad_inventario.Detalle.ForEach(x => { var Detalle = new BE_StockTransferLine { FromWarehouseCode = entidad.SubAlmacen, WarehouseCode = AlmacenDestino, ItemCode = x.CodigoArticulo, Quantity = (double)x.Cantidad, BaseLine = null, BaseEntry = null, BaseType = null, LineNum = LineNum, BatchNumbers = new List() }; StockTransfer.StockTransferLines.Add(Detalle); LineNum++; }); // == REALIZA DISTRIBUCION DE STOCK POR LOTE / ALMACEN StockTransfer.StockTransferLines.ForEach(line => { #region CONSULTA A HANA List ListaStock = HelperStock.Get(line.ItemCode, entidad.SubAlmacen); var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock.OrderBy(x => x.ExpDate).ToList(); var cantidadStock = ListaStock.Sum(x => x.OnHandQty); if (cantidadStock < line.Quantity) { throw new Exception($"El producto {line.ItemCode} no cuenta con stock suficiente"); } else { 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 }); var jsonForma = Newtonsoft.Json.JsonConvert.SerializeObject(StockTransfer); var ResultTransaction = stockTransferRepository.StockTransfer(StockTransfer).Result; if (ResultTransaction.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(ResultTransaction.Message.ToString(), entidad); } DocEntry = (int)ResultTransaction.Data.DocEntry; DocNum = (int)ResultTransaction.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); } } //=== TIPO DE INVENTARIO POR CONSUMO if (entidad.TipoInventario == "03") { //=== INGRESO DE MERCANCIA if (entidad.TipoMovimiento == "01") { int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { 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 = entidad.TipoMovimientoSAP, U_ITC_WMS_NUMINV = entidad.NroInventario }; int LineNum = 0; entidad_inventario.Detalle.ForEach(detalle => { _InventoryGenEntries.DocumentLines.Add(new BE_InventoryGenEntriesLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = detalle.DescripcionArticulo, Quantity = (double)detalle.Cantidad, LineNum = LineNum, PriceAfterVAT = detalle.PrecioPromedio, LineTotal = detalle.PrecioPromedio * (double)detalle.Cantidad, WarehouseCode = entidad.SubAlmacen, AccountCode = CuentaContable, CostingCode = detalle.CentroCosto ?? "", BatchNumbers = new List() { new BE_InventoryGenEntriesBatchNumbers() { BatchNumber = DateTime.Now.ToString("yyyyMMddhhmmss"), Quantity = (double)detalle.Cantidad } } }); 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); } DocEntry = (int)inventoryGenEntries_result.Data.DocEntry; DocNum = (int)inventoryGenEntries_result.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); // return resultadoTransaccion.GetInformacionResultado((int)inventoryGenEntries_result.Data.DocEntry, inventoryGenEntries_result.Data.DocNum.ToString(), "Registrado Correctamente", entidad); } //=== SALIDA DE MERCANCIA if (entidad.TipoMovimiento == "02") { int DocEntry = 0; int DocNum = 0; foreach (var entidad_inventario in ListaxLista) { BE_InventoryGenExits _InventoryGenExits = new BE_InventoryGenExits() { DocObjectCode = "oInventoryGenExit", DocDate = DateTime.Now, DocDueDate = DateTime.Now, PaymentGroupCode = "-2", DocCurrency = "S/", DocRate = 1, DocumentLines = new List(), U_SYP_TPOSALME = entidad.TipoMovimientoSAP, U_ITC_WMS_NUMINV = entidad.NroInventario }; int LineNum = 0; entidad_inventario.Detalle.ForEach(detalle => { _InventoryGenExits.DocumentLines.Add(new BE_InventoryGenExitsLine() { Currency = "S/", ItemCode = detalle.CodigoArticulo, ItemDescription = detalle.DescripcionArticulo, Quantity = (double)detalle.Cantidad, LineNum = LineNum, PriceAfterVAT = detalle.PrecioPromedio, LineTotal = detalle.PrecioPromedio * (double)detalle.Cantidad, WarehouseCode = entidad.SubAlmacen, AccountCode = CuentaContable, BatchNumbers = new List(), CostingCode = detalle.CentroCosto ?? "", }); LineNum++; }); _InventoryGenExits.DocumentLines.ForEach(line => { #region CONSULTA A HANA List ListaStock = HelperStock.Get(line.ItemCode, entidad.SubAlmacen); var CantidadPendiente = line.Quantity; var ListOrdenadaFecha = ListaStock.OrderBy(x => x.ExpDate).ToList(); var cantidadStock = ListaStock.Sum(x => x.OnHandQty); if (cantidadStock < line.Quantity) { throw new Exception($"El producto {line.ItemCode} no cuenta con stock suficiente"); } else { ListOrdenadaFecha.ForEach(Lote => { if (CantidadPendiente > 0) { if (Lote.OnHandQty >= CantidadPendiente) { line.BatchNumbers.Add(new BE_InventoryGenExitsBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = CantidadPendiente }); CantidadPendiente = 0; } else if (Lote.OnHandQty < CantidadPendiente) { line.BatchNumbers.Add(new BE_InventoryGenExitsBatchNumbers() { BatchNumber = Lote.DistNumber, Quantity = Lote.OnHandQty }); CantidadPendiente -= Lote.OnHandQty; } } }); } #endregion }); InventoryGenExitsRepository inventoryGenExits = new InventoryGenExitsRepository(_clientFactory, _configuration, context); var inventoryGenExits_result = inventoryGenExits.SetCreateInventoryGenExits(_InventoryGenExits, false).Result; if (inventoryGenExits_result.StatusCode == -1) { return resultadoTransaccion.GetInformacionResultado(inventoryGenExits_result.Message.ToString(), entidad); } DocEntry = (int)inventoryGenExits_result.Data.DocEntry; DocNum = (int)inventoryGenExits_result.Data.DocNum; }; return resultadoTransaccion.GetInformacionResultado(DocEntry, DocNum.ToString(), "Registrado Correctamente", entidad); //return resultadoTransaccion.GetInformacionResultado((int)inventoryGenExits_result.Data.DocEntry, inventoryGenExits_result.Data.DocNum.ToString(), "Registrado Correctamente", entidad); } } return resultadoTransaccion.GetInformacionResultado(0, "", "Registrado Correctamente", entidad); } catch (Exception ex) { return resultadoTransaccion.GetInformacionResultado(ex.Message.ToString(), entidad); } }); } } }