Files
itca_api_sap_wms/Net.Data/WMS/SolicitudTransferencia/SolicitudTransferenciaRepository.cs
T

100 lines
4.7 KiB
C#
Raw Normal View History

using Microsoft.Extensions.Configuration;
using Net.Business.Entities;
using Net.Business.Entities.ServicesLayer.InventoryTransferRequest;
using Net.Business.Entities.WMS.SolicitudTransferencia;
using Net.Connection.ServiceLayer;
using Net.CrossCotting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Net.Data.WMS.SolicitudTransferencia
{
// Modulo 100% nuevo (sin equivalente en el .NET original) - porte 1:1 de
// itca_api_sap_wms_python/app/services/solicitud_transferencia_service.py.
// Actualiza y cierra documentos InventoryTransferRequests (Solicitud de
// Traslado) en SAP Business One via Service Layer. Ver
// docs/SOLICITUD_TRANSFERENCIA.md para el detalle completo del contrato.
public class SolicitudTransferenciaRepository : ISolicitudTransferenciaRepository
{
private readonly string _aplicacionName;
private readonly IConfiguration _configuration;
private readonly IHttpClientFactory _clientFactory;
public SolicitudTransferenciaRepository(IHttpClientFactory clientFactory, IConfiguration configuration)
{
_aplicacionName = GetType().Name;
_configuration = configuration;
_clientFactory = clientFactory;
}
// Devuelve null en exito (el caller arma un BE_ResultadoTransaccion 200 con
// body - ver el controller; no responde 204 porque muchos clientes HTTP,
// incluido HttpClient de .NET, no leen el body de un 204 - ver
// docs/SOLICITUD_TRANSFERENCIA.md).
//
// El PATCH SOLO actualiza cantidades de linea existentes en SAP - no toca
// fechas, almacenes ni ningun otro campo del documento - y ELIMINA una
// linea cuando Cantidad = 0. Confirmado contra el Service Layer real de QA:
// alcanza con mandar LineNum + Quantity por linea junto con el header
// B1S-ReplaceCollectionsOnPatch: true, que le indica a Service Layer que
// trate StockTransferLines como reemplazo COMPLETO del array, no un merge
// parcial. SAP ademas RECHAZA una linea mandada explicita con Quantity: 0,
// por eso se omite del array en vez de mandarla en cero.
//
// Al ser un reemplazo completo, SAP TAMBIEN exige el campo Rate en cada
// linea. Se manda Rate: 0.0 fijo (request validado contra SAP); esto pisa
// el Rate que tuviera la linea en el documento. No se valida que la linea
// exista: si no existe, el error lo devuelve SAP.
public async Task<BE_ResultadoTransaccion<object>> Update(int docEntry, BE_SolicitudTransferenciaPatchRequest entidad)
{
ResultadoTransaccion<object> resultadoTransaccion = new ResultadoTransaccion<object>("Update", _aplicacionName);
try
{
var connectServiceLayer = new ConnectionServiceLayer(_configuration, _clientFactory);
var lines = new List<object>();
foreach (var detalle in entidad.Detalle ?? new List<BE_SolicitudTransferenciaPatchDetalle>())
{
if (detalle.Cantidad == 0) continue;
lines.Add(new { LineNum = detalle.Linea, Quantity = detalle.Cantidad, Rate = 0.0 });
}
await connectServiceLayer.PatchNoContentAsync(
$"InventoryTransferRequests({docEntry})",
new { StockTransferLines = lines },
new Dictionary<string, string> { ["B1S-ReplaceCollectionsOnPatch"] = "true" });
return null;
}
catch (Exception ex)
{
return resultadoTransaccion.GetInformacionResultado(ex.Message.ToString(), (object)entidad);
}
}
// Cierra el documento completo. Funcionalidad nueva (no existe en el .NET
// original) - SAP Service Layer cierra documentos via POST a la sub-ruta
// /Close, mismo patron que Picking/HojaRuta/Cerrar. Devuelve null en exito
// (el caller arma el BE_ResultadoTransaccion 200 con body).
public async Task<BE_ResultadoTransaccion<object>> Cerrar(int docEntry)
{
ResultadoTransaccion<object> resultadoTransaccion = new ResultadoTransaccion<object>("Cerrar", _aplicacionName);
try
{
var connectServiceLayer = new ConnectionServiceLayer(_configuration, _clientFactory);
await connectServiceLayer.PostActionAsync($"InventoryTransferRequests({docEntry})/Close");
return null;
}
catch (Exception ex)
{
return resultadoTransaccion.GetInformacionResultado(ex.Message.ToString(), (object)null);
}
}
}
}