Files

236 lines
14 KiB
C#

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<object>, 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<BE_ResultadoTransaccion<object>> Create(BE_TransferenciaRequest entidad)
{
_metodoName = regex.Match(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name).Groups[1].Value.ToString();
ResultadoTransaccion<object> resultadoTransaccion = new ResultadoTransaccion<object>(_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<BE_StockTransferLine>()
};
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<BE_StockTransferLineBatchNumber>()
};
StockTransfer.StockTransferLines.Add(Detalle);
});
// == REALIZA DISTRIBUCION DE STOCK POR LOTE / ALMACEN
StockTransfer.StockTransferLines.ForEach(line =>
{
#region CONSULTA A HANA
List<BE_ItemStock> 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
// Proceso: factura de reserva -> WMS recibe por partes y crea una entrada por recepcion (todas a ALM99) -> costeo en SAP ->
// WMS notifica UNA transferencia por entrada, con numorden = DocNum de la factura de reserva y en el detalle los
// articulos/cantidades de esa entrada. Detalle completo y diagnostico en docs/TRANSFERENCIA_IMPORTACION.md.
// Casos: (1) DocEntryEM informado -> se usa esa entrada; (2) sin DocEntryEM -> se busca la entrada de la factura que
// coincida con el detalle y no tenga transferencia (EntradaImportacion.Elegir); (3) la factura no tiene entradas ->
// como antes, lotes del stock de HANA sin amarre.
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<BE_PurchaseDeliveryNotesBatchNumbers>())
.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<BE_StockTransferLine>();
foreach (var l in pdn.DocumentLines)
{
var lotes = (l.BatchNumbers ?? new List<BE_PurchaseDeliveryNotesBatchNumbers>())
.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);
}
});
}
}
}