using System.Data; using Microsoft.Data.SqlClient; using Dapper; using MotoresArgentinosV2.Core.Interfaces; using MotoresArgentinosV2.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MotoresArgentinosV2.Core.Entities; using System.Text.Json; using Microsoft.Extensions.Logging; namespace MotoresArgentinosV2.Infrastructure.Services; public class LegacyPaymentService : ILegacyPaymentService { private readonly string _internetConn; private readonly MotoresV2DbContext _v2Context; private readonly IConfiguration _config; private readonly ILogger _logger; public LegacyPaymentService(IConfiguration config, MotoresV2DbContext v2Context, ILogger logger) { _internetConn = config.GetConnectionString("eldia") ?? ""; _v2Context = v2Context; _config = config; _logger = logger; } public async Task GetAdPriceAsync(string category, bool isFeatured) { // Consulta real al Legacy para obtener precio using IDbConnection db = new SqlConnection(_internetConn); var parametros = new { tarea = category, paquete = isFeatured ? 1 : 0 }; try { var result = await db.QueryFirstOrDefaultAsync( "SPDATOSAVISOS", parametros, commandType: CommandType.StoredProcedure); if (result != null) { // El SP devuelve IMPORTE_TOTSINIVA que incluye el recargo destacado pero SIN IVA // El IVA está hardcodeado al 10.5% en la lógica legacy decimal neto = (decimal)result.IMPORTE_TOTSINIVA; decimal iva = neto * 0.105m; return new AdPriceResult(neto, iva, neto + iva, "ARS"); } else { throw new Exception("El SP legacy devolvió null para los parámetros dados."); } } catch (Exception ex) { _logger.LogError(ex, "Error crítico consultando SPDATOSAVISOS legacy. No se puede determinar precio."); throw; // Re-throw to prevent hardcoded fallback } } public async Task ProcessPaymentResponseAsync(string operationCode, string status, string providerData) { _logger.LogInformation("Procesando pago Legacy. Op: {OpCode}, Status: {Status}", operationCode, status); // 1. Buscamos la transacción en V2 para obtener los datos necesarios. var tx = await _v2Context.Transactions .Include(t => t.Ad) .ThenInclude(a => a.User) .FirstOrDefaultAsync(t => t.OperationCode == operationCode); // Si no encontramos la transacción, no podemos continuar. if (tx == null) { _logger.LogError("No se encontró la transacción V2 con OperationCode {OpCode} para sincronizar con Legacy.", operationCode); return false; } // Si el pago no fue aprobado, no hay nada que insertar en legacy. if (!status.Equals("APPROVED", StringComparison.OrdinalIgnoreCase)) { return true; // La operación no falló, simplemente no aplica. } try { var ad = tx.Ad; if (ad == null || ad.User == null) { _logger.LogError("La transacción {OpCode} no tiene un aviso o usuario asociado.", operationCode); return false; } decimal importeNeto = Math.Round(tx.Amount / 1.105m, 2); decimal importeIva = Math.Round(tx.Amount - importeNeto, 2); var p = new DynamicParameters(); p.Add("@tipo", ad.VehicleTypeID == 1 ? "A" : "M"); p.Add("@nro_operacion", tx.TransactionID); p.Add("@id_cliente", ad.UserID); p.Add("@tipodoc", 96); p.Add("@nro_doc", "0"); p.Add("@razon", $"{ad.User.FirstName} {ad.User.LastName}".Trim().ToUpper()); p.Add("@calle", ""); p.Add("@numero", ""); p.Add("@localidad", "LA PLATA"); p.Add("@codigopostal", "1900"); p.Add("@telefono", ad.ContactPhone ?? ""); p.Add("@email", ad.User.Email); p.Add("@id_tipoiva", 1); p.Add("@porcentaje_iva1", 10.5m); p.Add("@porcentaje_iva2", 0); p.Add("@porcentaje_percepcion", 0); p.Add("@id_tipoaviso", 16); p.Add("@nombreaviso", "INTERNET"); p.Add("@id_rubro", 193); p.Add("@id_subrubro", 0); p.Add("@id_combinado", 0); p.Add("@porcentaje_combinado", 0); p.Add("@fecha_inicio", DateTime.Now.Date, DbType.DateTime); p.Add("@cant_dias", 30); p.Add("@dias_corridos", true); p.Add("@palabras", 20); p.Add("@centimetros", 0); p.Add("@columnas", 0); p.Add("@id_tarjeta", 1); p.Add("@nro_tarjeta", "0000000000000000"); p.Add("@cvc_tarjeta", 111); p.Add("@vencimiento", DateTime.Now.AddDays(1), DbType.DateTime); p.Add("@calle_envio", ""); p.Add("@numero_envio", ""); p.Add("@localidad_envio", ""); p.Add("@tarifa", importeNeto); p.Add("@importe_aviso", importeNeto); p.Add("@importe_iva1", importeIva); p.Add("@importe_iva2", 0); p.Add("@importe_percepcion", 0); p.Add("@cantavi", 1); p.Add("@paquete", 1); p.Add("@destacado", ad.IsFeatured); using (var dbInternet = new SqlConnection(_internetConn)) { // El SP legacy convierte internamente @fecha_inicio a un string 'dd/mm/yyyy'. // Esto falla en servidores con formato 'mdy'. // Al anteponer 'SET DATEFORMAT dmy;', forzamos a la sesión a interpretar // correctamente el formato 'dd/mm/yyyy' y se soluciona el error. var sql = @" SET DATEFORMAT dmy; EXEC spInsertaAvisos @tipo, @nro_operacion, @id_cliente, @tipodoc, @nro_doc, @razon, @calle, @numero, @localidad, @codigopostal, @telefono, @email, @id_tipoiva, @porcentaje_iva1, @porcentaje_iva2, @porcentaje_percepcion, @id_tipoaviso, @nombreaviso, @id_rubro, @id_subrubro, @id_combinado, @porcentaje_combinado, @fecha_inicio, @cant_dias, @dias_corridos, @palabras, @centimetros, @columnas, @id_tarjeta, @nro_tarjeta, @cvc_tarjeta, @vencimiento, @calle_envio, @numero_envio, @localidad_envio, @tarifa, @importe_aviso, @importe_iva1, @importe_iva2, @importe_percepcion, @cantavi, @paquete, @destacado; "; await dbInternet.ExecuteAsync(sql, p); } _logger.LogInformation("Aviso insertado en Legacy AvisosWeb correctamente para Op: {OpCode}", operationCode); return true; } catch (Exception ex) { _logger.LogError(ex, "Error crítico insertando en Legacy AvisosWeb. Op: {OpCode}", operationCode); // Devolvemos false para que el servicio que lo llamó sepa que la integración falló. return false; } } }