165 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			165 lines
		
	
	
		
			7.9 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 SalidaOtroDestinoService : ISalidaOtroDestinoService
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        private readonly ISalidaOtroDestinoRepository _salidaRepository;
							 | 
						||
| 
								 | 
							
								        private readonly IPublicacionRepository _publicacionRepository;
							 | 
						||
| 
								 | 
							
								        private readonly IOtroDestinoRepository _otroDestinoRepository;
							 | 
						||
| 
								 | 
							
								        private readonly DbConnectionFactory _connectionFactory;
							 | 
						||
| 
								 | 
							
								        private readonly ILogger<SalidaOtroDestinoService> _logger;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public SalidaOtroDestinoService(
							 | 
						||
| 
								 | 
							
								            ISalidaOtroDestinoRepository salidaRepository,
							 | 
						||
| 
								 | 
							
								            IPublicacionRepository publicacionRepository,
							 | 
						||
| 
								 | 
							
								            IOtroDestinoRepository otroDestinoRepository,
							 | 
						||
| 
								 | 
							
								            DbConnectionFactory connectionFactory,
							 | 
						||
| 
								 | 
							
								            ILogger<SalidaOtroDestinoService> logger)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            _salidaRepository = salidaRepository;
							 | 
						||
| 
								 | 
							
								            _publicacionRepository = publicacionRepository;
							 | 
						||
| 
								 | 
							
								            _otroDestinoRepository = otroDestinoRepository;
							 | 
						||
| 
								 | 
							
								            _connectionFactory = connectionFactory;
							 | 
						||
| 
								 | 
							
								            _logger = logger;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        private async Task<SalidaOtroDestinoDto> MapToDto(SalidaOtroDestino salida)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (salida == null) return null!; // Debería ser manejado por el llamador
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            var publicacion = await _publicacionRepository.GetByIdSimpleAsync(salida.IdPublicacion);
							 | 
						||
| 
								 | 
							
								            var destino = await _otroDestinoRepository.GetByIdAsync(salida.IdDestino);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return new SalidaOtroDestinoDto
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                IdParte = salida.IdParte,
							 | 
						||
| 
								 | 
							
								                IdPublicacion = salida.IdPublicacion,
							 | 
						||
| 
								 | 
							
								                NombrePublicacion = publicacion?.Nombre ?? "Publicación Desconocida",
							 | 
						||
| 
								 | 
							
								                IdDestino = salida.IdDestino,
							 | 
						||
| 
								 | 
							
								                NombreDestino = destino?.Nombre ?? "Destino Desconocido",
							 | 
						||
| 
								 | 
							
								                Fecha = salida.Fecha.ToString("yyyy-MM-dd"),
							 | 
						||
| 
								 | 
							
								                Cantidad = salida.Cantidad,
							 | 
						||
| 
								 | 
							
								                Observacion = salida.Observacion
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public async Task<IEnumerable<SalidaOtroDestinoDto>> ObtenerTodosAsync(DateTime? fechaDesde, DateTime? fechaHasta, int? idPublicacion, int? idDestino)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            var salidas = await _salidaRepository.GetAllAsync(fechaDesde, fechaHasta, idPublicacion, idDestino);
							 | 
						||
| 
								 | 
							
								            var dtos = new List<SalidaOtroDestinoDto>();
							 | 
						||
| 
								 | 
							
								            foreach (var salida in salidas)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                dtos.Add(await MapToDto(salida));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return dtos;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public async Task<SalidaOtroDestinoDto?> ObtenerPorIdAsync(int idParte)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            var salida = await _salidaRepository.GetByIdAsync(idParte);
							 | 
						||
| 
								 | 
							
								            return salida == null ? null : await MapToDto(salida);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public async Task<(SalidaOtroDestinoDto? Salida, string? Error)> CrearAsync(CreateSalidaOtroDestinoDto createDto, int idUsuario)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (await _publicacionRepository.GetByIdSimpleAsync(createDto.IdPublicacion) == null)
							 | 
						||
| 
								 | 
							
								                return (null, "La publicación especificada no existe o no está habilitada.");
							 | 
						||
| 
								 | 
							
								            if (await _otroDestinoRepository.GetByIdAsync(createDto.IdDestino) == null)
							 | 
						||
| 
								 | 
							
								                return (null, "El destino especificado no existe.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            var nuevaSalida = new SalidaOtroDestino
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                IdPublicacion = createDto.IdPublicacion,
							 | 
						||
| 
								 | 
							
								                IdDestino = createDto.IdDestino,
							 | 
						||
| 
								 | 
							
								                Fecha = createDto.Fecha.Date,
							 | 
						||
| 
								 | 
							
								                Cantidad = createDto.Cantidad,
							 | 
						||
| 
								 | 
							
								                Observacion = createDto.Observacion
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            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 salidaCreada = await _salidaRepository.CreateAsync(nuevaSalida, idUsuario, transaction);
							 | 
						||
| 
								 | 
							
								                if (salidaCreada == null) throw new DataException("Error al registrar la salida.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                transaction.Commit();
							 | 
						||
| 
								 | 
							
								                _logger.LogInformation("SalidaOtroDestino ID {Id} creada por Usuario ID {UserId}.", salidaCreada.IdParte, idUsuario);
							 | 
						||
| 
								 | 
							
								                return (await MapToDto(salidaCreada), null);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            catch (Exception ex)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                try { transaction.Rollback(); } catch { }
							 | 
						||
| 
								 | 
							
								                _logger.LogError(ex, "Error CrearAsync SalidaOtroDestino para Pub ID {IdPub}", createDto.IdPublicacion);
							 | 
						||
| 
								 | 
							
								                return (null, $"Error interno: {ex.Message}");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public async Task<(bool Exito, string? Error)> ActualizarAsync(int idParte, UpdateSalidaOtroDestinoDto 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 salidaExistente = await _salidaRepository.GetByIdAsync(idParte); // Obtener dentro de TX
							 | 
						||
| 
								 | 
							
								                if (salidaExistente == null) return (false, "Registro de salida no encontrado.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                // Actualizar solo los campos permitidos
							 | 
						||
| 
								 | 
							
								                salidaExistente.Cantidad = updateDto.Cantidad;
							 | 
						||
| 
								 | 
							
								                salidaExistente.Observacion = updateDto.Observacion;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                var actualizado = await _salidaRepository.UpdateAsync(salidaExistente, idUsuario, transaction);
							 | 
						||
| 
								 | 
							
								                if (!actualizado) throw new DataException("Error al actualizar la salida.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                transaction.Commit();
							 | 
						||
| 
								 | 
							
								                _logger.LogInformation("SalidaOtroDestino ID {Id} actualizada por Usuario ID {UserId}.", idParte, 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 SalidaOtroDestino ID: {Id}", idParte);
							 | 
						||
| 
								 | 
							
								                return (false, $"Error interno: {ex.Message}");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public async Task<(bool Exito, string? Error)> EliminarAsync(int idParte, 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 salidaExistente = await _salidaRepository.GetByIdAsync(idParte);
							 | 
						||
| 
								 | 
							
								                if (salidaExistente == null) return (false, "Registro de salida no encontrado.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                var eliminado = await _salidaRepository.DeleteAsync(idParte, idUsuario, transaction);
							 | 
						||
| 
								 | 
							
								                if (!eliminado) throw new DataException("Error al eliminar la salida.");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                transaction.Commit();
							 | 
						||
| 
								 | 
							
								                _logger.LogInformation("SalidaOtroDestino ID {Id} eliminada por Usuario ID {UserId}.", idParte, 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 SalidaOtroDestino ID: {Id}", idParte);
							 | 
						||
| 
								 | 
							
								                return (false, $"Error interno: {ex.Message}");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |