54 lines
2.9 KiB
C#
54 lines
2.9 KiB
C#
using Net.Business.Entities.WMS.Transferencia;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Net.Data.WMS.Transferencia
|
|
{
|
|
// Elige la Entrada de Mercaderia de una Factura de Reserva que corresponde a una transferencia desde ALM99.
|
|
// WMS recibe por partes: cada entrada tiene su propio juego de articulos/cantidades, y WMS notifica una
|
|
// transferencia por entrada con ese mismo juego (se compara solo ItemCode y cantidad, no el numero de item).
|
|
public static class EntradaImportacion
|
|
{
|
|
private const decimal Tolerancia = 0.0001m;
|
|
|
|
// Devuelve el DocEntry de la entrada elegida, o 0 con el motivo en "error".
|
|
public static int Elegir(string docNumFactura, List<BE_EntradaImportacionLinea> filas, List<BE_TransferenciaDetalle> detalle, out string error)
|
|
{
|
|
error = null;
|
|
var pedido = (detalle ?? new List<BE_TransferenciaDetalle>())
|
|
.GroupBy(x => x.CodigoArticulo)
|
|
.ToDictionary(g => g.Key, g => g.Sum(x => x.CantidadPedida));
|
|
|
|
var entradas = filas.GroupBy(x => x.DocEntry).OrderBy(g => g.Key).ToList();
|
|
var coincidentes = entradas.Where(g => Coincide(g, pedido)).ToList();
|
|
|
|
// La mas antigua que aun no tenga transferencia
|
|
var libre = coincidentes.FirstOrDefault(g => !g.Any(l => l.TransferenciaDocEntry > 0));
|
|
if (libre != null)
|
|
{
|
|
return libre.Key;
|
|
}
|
|
|
|
if (coincidentes.Count > 0)
|
|
{
|
|
var detalleYa = coincidentes.Select(g => $"entrada {g.First().DocNum} (DocEntry {g.Key}) ya transferida en la transferencia {g.First(l => l.TransferenciaDocEntry > 0).TransferenciaDocEntry}");
|
|
error = $"SAP: Todas las entradas de la factura de reserva {docNumFactura} con esos articulos y cantidades ya estan transferidas: {string.Join("; ", detalleYa)}";
|
|
return 0;
|
|
}
|
|
|
|
var pendientes = entradas.Where(g => !g.Any(l => l.TransferenciaDocEntry > 0)).Select(g => $"{g.First().DocNum}");
|
|
error = $"SAP: Ninguna entrada de la factura de reserva {docNumFactura} coincide con los articulos y cantidades enviados. " +
|
|
$"Entradas pendientes de transferir (DocNum): {(pendientes.Any() ? string.Join(", ", pendientes) : "ninguna")}";
|
|
return 0;
|
|
}
|
|
|
|
private static bool Coincide(IGrouping<int, BE_EntradaImportacionLinea> entrada, Dictionary<string, decimal> pedido)
|
|
{
|
|
var enEntrada = entrada.GroupBy(x => x.ItemCode).ToDictionary(g => g.Key, g => g.Sum(x => x.Quantity));
|
|
if (enEntrada.Count != pedido.Count) return false;
|
|
return enEntrada.All(kv => pedido.TryGetValue(kv.Key, out decimal cant) && Math.Abs(cant - kv.Value) <= Tolerancia);
|
|
}
|
|
}
|
|
}
|