171 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using GestionIntegral.Api.Data;
 | |
| using GestionIntegral.Api.Data.Repositories.Distribucion;
 | |
| using GestionIntegral.Api.Dtos.Distribucion;
 | |
| using GestionIntegral.Api.Models.Distribucion;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Data;
 | |
| using System.Linq;
 | |
| using System.Threading.Tasks;
 | |
| 
 | |
| namespace GestionIntegral.Api.Services.Distribucion
 | |
| {
 | |
|     public class ControlDevolucionesService : IControlDevolucionesService
 | |
|     {
 | |
|         private readonly IControlDevolucionesRepository _controlDevRepo;
 | |
|         private readonly IEmpresaRepository _empresaRepository; // Para validar IdEmpresa y obtener nombre
 | |
|         private readonly DbConnectionFactory _connectionFactory;
 | |
|         private readonly ILogger<ControlDevolucionesService> _logger;
 | |
| 
 | |
|         public ControlDevolucionesService(
 | |
|             IControlDevolucionesRepository controlDevRepo,
 | |
|             IEmpresaRepository empresaRepository,
 | |
|             DbConnectionFactory connectionFactory,
 | |
|             ILogger<ControlDevolucionesService> logger)
 | |
|         {
 | |
|             _controlDevRepo = controlDevRepo;
 | |
|             _empresaRepository = empresaRepository;
 | |
|             _connectionFactory = connectionFactory;
 | |
|             _logger = logger;
 | |
|         }
 | |
| 
 | |
|         private async Task<ControlDevolucionesDto> MapToDto(ControlDevoluciones control)
 | |
|         {
 | |
|             if (control == null) return null!;
 | |
|             var empresa = await _empresaRepository.GetByIdAsync(control.IdEmpresa);
 | |
|             return new ControlDevolucionesDto
 | |
|             {
 | |
|                 IdControl = control.IdControl,
 | |
|                 IdEmpresa = control.IdEmpresa,
 | |
|                 NombreEmpresa = empresa?.Nombre ?? "Empresa Desconocida",
 | |
|                 Fecha = control.Fecha.ToString("yyyy-MM-dd"),
 | |
|                 Entrada = control.Entrada,
 | |
|                 Sobrantes = control.Sobrantes,
 | |
|                 Detalle = control.Detalle,
 | |
|                 SinCargo = control.SinCargo
 | |
|             };
 | |
|         }
 | |
| 
 | |
|         public async Task<IEnumerable<ControlDevolucionesDto>> ObtenerTodosAsync(DateTime? fechaDesde, DateTime? fechaHasta, int? idEmpresa)
 | |
|         {
 | |
|             var controles = await _controlDevRepo.GetAllAsync(fechaDesde, fechaHasta, idEmpresa);
 | |
|             var dtos = new List<ControlDevolucionesDto>();
 | |
|             foreach (var control in controles)
 | |
|             {
 | |
|                 dtos.Add(await MapToDto(control));
 | |
|             }
 | |
|             return dtos;
 | |
|         }
 | |
| 
 | |
|         public async Task<ControlDevolucionesDto?> ObtenerPorIdAsync(int idControl)
 | |
|         {
 | |
|             var control = await _controlDevRepo.GetByIdAsync(idControl);
 | |
|             return control == null ? null : await MapToDto(control);
 | |
|         }
 | |
| 
 | |
|         public async Task<(ControlDevolucionesDto? Control, string? Error)> CrearAsync(CreateControlDevolucionesDto createDto, int idUsuario)
 | |
|         {
 | |
|             var empresa = await _empresaRepository.GetByIdAsync(createDto.IdEmpresa);
 | |
|             if (empresa == null)
 | |
|                 return (null, "La empresa especificada no existe.");
 | |
| 
 | |
|             // Validar que no exista ya un control para esa empresa y fecha
 | |
|             if (await _controlDevRepo.GetByEmpresaAndFechaAsync(createDto.IdEmpresa, createDto.Fecha.Date) != null)
 | |
|             {
 | |
|                 return (null, $"Ya existe un control de devoluciones para la empresa '{empresa.Nombre}' en la fecha {createDto.Fecha:dd/MM/yyyy}.");
 | |
|             }
 | |
| 
 | |
|             var nuevoControl = new ControlDevoluciones
 | |
|             {
 | |
|                 IdEmpresa = createDto.IdEmpresa,
 | |
|                 Fecha = createDto.Fecha.Date,
 | |
|                 Entrada = createDto.Entrada,
 | |
|                 Sobrantes = createDto.Sobrantes,
 | |
|                 Detalle = createDto.Detalle,
 | |
|                 SinCargo = createDto.SinCargo
 | |
|             };
 | |
| 
 | |
|             using var connection = _connectionFactory.CreateConnection();
 | |
|             if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
 | |
|             using var transaction = connection.BeginTransaction();
 | |
|             try
 | |
|             {
 | |
|                 var controlCreado = await _controlDevRepo.CreateAsync(nuevoControl, idUsuario, transaction);
 | |
|                 if (controlCreado == null) throw new DataException("Error al registrar el control de devoluciones.");
 | |
| 
 | |
|                 transaction.Commit();
 | |
|                 _logger.LogInformation("ControlDevoluciones ID {Id} creado por Usuario ID {UserId}.", controlCreado.IdControl, idUsuario);
 | |
|                 return (await MapToDto(controlCreado), null);
 | |
|             }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 try { transaction.Rollback(); } catch { }
 | |
|                 _logger.LogError(ex, "Error CrearAsync ControlDevoluciones para Empresa ID {IdEmpresa}, Fecha {Fecha}", createDto.IdEmpresa, createDto.Fecha);
 | |
|                 return (null, $"Error interno: {ex.Message}");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public async Task<(bool Exito, string? Error)> ActualizarAsync(int idControl, UpdateControlDevolucionesDto updateDto, int idUsuario)
 | |
|         {
 | |
|             using var connection = _connectionFactory.CreateConnection();
 | |
|             if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
 | |
|             using var transaction = connection.BeginTransaction();
 | |
|             try
 | |
|             {
 | |
|                 var controlExistente = await _controlDevRepo.GetByIdAsync(idControl); // Obtener dentro de TX
 | |
|                 if (controlExistente == null) return (false, "Control de devoluciones no encontrado.");
 | |
| 
 | |
|                 // IdEmpresa y Fecha no se modifican
 | |
|                 controlExistente.Entrada = updateDto.Entrada;
 | |
|                 controlExistente.Sobrantes = updateDto.Sobrantes;
 | |
|                 controlExistente.Detalle = updateDto.Detalle;
 | |
|                 controlExistente.SinCargo = updateDto.SinCargo;
 | |
| 
 | |
|                 var actualizado = await _controlDevRepo.UpdateAsync(controlExistente, idUsuario, transaction);
 | |
|                 if (!actualizado) throw new DataException("Error al actualizar el control de devoluciones.");
 | |
| 
 | |
|                 transaction.Commit();
 | |
|                 _logger.LogInformation("ControlDevoluciones ID {Id} actualizado por Usuario ID {UserId}.", idControl, idUsuario);
 | |
|                 return (true, null);
 | |
|             }
 | |
|             catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Registro no encontrado."); }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 try { transaction.Rollback(); } catch { }
 | |
|                 _logger.LogError(ex, "Error ActualizarAsync ControlDevoluciones ID: {Id}", idControl);
 | |
|                 return (false, $"Error interno: {ex.Message}");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public async Task<(bool Exito, string? Error)> EliminarAsync(int idControl, int idUsuario)
 | |
|         {
 | |
|             using var connection = _connectionFactory.CreateConnection();
 | |
|             if (connection is System.Data.Common.DbConnection dbConn) await dbConn.OpenAsync(); else connection.Open();
 | |
|             using var transaction = connection.BeginTransaction();
 | |
|             try
 | |
|             {
 | |
|                 var controlExistente = await _controlDevRepo.GetByIdAsync(idControl); // Obtener dentro de TX
 | |
|                 if (controlExistente == null) return (false, "Control de devoluciones no encontrado.");
 | |
| 
 | |
|                 // Aquí no hay dependencias directas que afecten saldos, es un registro informativo.
 | |
|                 // Se podría verificar si está "en uso" si alguna lógica de reporte o cierre depende de él,
 | |
|                 // pero por ahora, la eliminación es directa.
 | |
| 
 | |
|                 var eliminado = await _controlDevRepo.DeleteAsync(idControl, idUsuario, transaction);
 | |
|                 if (!eliminado) throw new DataException("Error al eliminar el control de devoluciones.");
 | |
| 
 | |
|                 transaction.Commit();
 | |
|                 _logger.LogInformation("ControlDevoluciones ID {Id} eliminado por Usuario ID {UserId}.", idControl, idUsuario);
 | |
|                 return (true, null);
 | |
|             }
 | |
|             catch (KeyNotFoundException) { try { transaction.Rollback(); } catch { } return (false, "Registro no encontrado."); }
 | |
|             catch (Exception ex)
 | |
|             {
 | |
|                 try { transaction.Rollback(); } catch { }
 | |
|                 _logger.LogError(ex, "Error EliminarAsync ControlDevoluciones ID: {Id}", idControl);
 | |
|                 return (false, $"Error interno: {ex.Message}");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |