146 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			146 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using GestionIntegral.Api.Data.Repositories; // Para IZonaRepository | ||
|  | using GestionIntegral.Api.Data.Repositories.Distribucion; | ||
|  | using GestionIntegral.Api.Dtos.Zonas; | ||
|  | using GestionIntegral.Api.Models.Distribucion; // Para Zona | ||
|  | using System.Collections.Generic; | ||
|  | using System.Linq; | ||
|  | using System.Threading.Tasks; | ||
|  | 
 | ||
|  | namespace GestionIntegral.Api.Services.Distribucion | ||
|  | { | ||
|  |     public class ZonaService : IZonaService | ||
|  |     { | ||
|  |         private readonly IZonaRepository _zonaRepository; | ||
|  |         private readonly ILogger<ZonaService> _logger; | ||
|  | 
 | ||
|  |         public ZonaService(IZonaRepository zonaRepository, ILogger<ZonaService> logger) | ||
|  |         { | ||
|  |             _zonaRepository = zonaRepository; | ||
|  |             _logger = logger; | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<IEnumerable<ZonaDto>> ObtenerTodasAsync(string? nombreFilter, string? descripcionFilter) | ||
|  |         { | ||
|  |             var zonas = await _zonaRepository.GetAllAsync(nombreFilter, descripcionFilter, soloActivas: true); // Solo activas por defecto | ||
|  |             // Mapeo Entidad -> DTO | ||
|  |             return zonas.Select(z => new ZonaDto | ||
|  |             { | ||
|  |                 IdZona = z.IdZona, | ||
|  |                 Nombre = z.Nombre, | ||
|  |                 Descripcion = z.Descripcion | ||
|  |             }); | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<ZonaDto?> ObtenerPorIdAsync(int id) | ||
|  |         { | ||
|  |             var zona = await _zonaRepository.GetByIdAsync(id, soloActivas: true); // Solo activa por defecto | ||
|  |             if (zona == null) return null; | ||
|  | 
 | ||
|  |             // Mapeo Entidad -> DTO | ||
|  |             return new ZonaDto | ||
|  |             { | ||
|  |                 IdZona = zona.IdZona, | ||
|  |                 Nombre = zona.Nombre, | ||
|  |                 Descripcion = zona.Descripcion | ||
|  |             }; | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<(ZonaDto? Zona, string? Error)> CrearAsync(CreateZonaDto createDto, int idUsuario) | ||
|  |         { | ||
|  |             // Validación: Nombre duplicado (entre zonas activas) | ||
|  |             if (await _zonaRepository.ExistsByNameAsync(createDto.Nombre, null, soloActivas: true)) | ||
|  |             { | ||
|  |                 return (null, "El nombre de la zona ya existe."); | ||
|  |             } | ||
|  | 
 | ||
|  |             var nuevaZona = new Zona | ||
|  |             { | ||
|  |                 Nombre = createDto.Nombre, | ||
|  |                 Descripcion = createDto.Descripcion, | ||
|  |                 Estado = true // Las zonas nuevas siempre están activas | ||
|  |             }; | ||
|  | 
 | ||
|  |             var zonaCreada = await _zonaRepository.CreateAsync(nuevaZona, idUsuario); | ||
|  | 
 | ||
|  |             if (zonaCreada == null) | ||
|  |             { | ||
|  |                 _logger.LogError("Falló la creación de la Zona en el repositorio para el nombre: {Nombre}", createDto.Nombre); | ||
|  |                 return (null, "Error al crear la zona en la base de datos."); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Mapeo de Entidad creada a DTO | ||
|  |             var zonaDto = new ZonaDto | ||
|  |             { | ||
|  |                 IdZona = zonaCreada.IdZona, | ||
|  |                 Nombre = zonaCreada.Nombre, | ||
|  |                 Descripcion = zonaCreada.Descripcion | ||
|  |             }; | ||
|  | 
 | ||
|  |             return (zonaDto, null); // Éxito | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateZonaDto updateDto, int idUsuario) | ||
|  |         { | ||
|  |             // Verificar si la zona existe y está activa para poder modificarla (regla de negocio) | ||
|  |             var zonaExistente = await _zonaRepository.GetByIdAsync(id, soloActivas: true); | ||
|  |             if (zonaExistente == null) | ||
|  |             { | ||
|  |                 // Podría no existir o estar inactiva | ||
|  |                 var zonaInactiva = await _zonaRepository.GetByIdAsync(id, soloActivas: false); | ||
|  |                 if (zonaInactiva != null) | ||
|  |                     return (false, "No se puede modificar una zona eliminada (inactiva)."); | ||
|  |                 else | ||
|  |                     return (false, "Zona no encontrada."); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Validación: Nombre duplicado (excluyendo el ID actual, entre zonas activas) | ||
|  |             if (await _zonaRepository.ExistsByNameAsync(updateDto.Nombre, id, soloActivas: true)) | ||
|  |             { | ||
|  |                 return (false, "El nombre de la zona ya existe para otro registro activo."); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Mapeo de DTO a Entidad para actualizar | ||
|  |             zonaExistente.Nombre = updateDto.Nombre; | ||
|  |             zonaExistente.Descripcion = updateDto.Descripcion; | ||
|  |             // No modificamos el estado aquí, solo nombre y descripción | ||
|  | 
 | ||
|  |             var actualizado = await _zonaRepository.UpdateAsync(zonaExistente, idUsuario); | ||
|  | 
 | ||
|  |             if (!actualizado) | ||
|  |             { | ||
|  |                 _logger.LogError("Falló la actualización de la Zona en el repositorio para el ID: {Id}", id); | ||
|  |                 return (false, "Error al actualizar la zona en la base de datos."); | ||
|  |             } | ||
|  |             return (true, null); // Éxito | ||
|  |         } | ||
|  | 
 | ||
|  |         public async Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario) | ||
|  |         { | ||
|  |             // Verificar si la zona existe (incluso si está inactiva, para evitar errores) | ||
|  |             var zonaExistente = await _zonaRepository.GetByIdAsync(id, soloActivas: false); | ||
|  |             if (zonaExistente == null) | ||
|  |             { | ||
|  |                 return (false, "Zona no encontrada."); | ||
|  |             } | ||
|  |             // Si ya está inactiva, consideramos la operación exitosa (idempotencia) | ||
|  |             if (!zonaExistente.Estado) { | ||
|  |                 return (true, null); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Validación: No se puede eliminar si está en uso por distribuidores o canillas activos | ||
|  |             if (await _zonaRepository.IsInUseAsync(id)) | ||
|  |             { | ||
|  |                 return (false, "No se puede eliminar. La zona está asignada a distribuidores o canillas activos."); | ||
|  |             } | ||
|  | 
 | ||
|  |             // Realizar el Soft Delete | ||
|  |             var eliminado = await _zonaRepository.SoftDeleteAsync(id, idUsuario); | ||
|  |             if (!eliminado) | ||
|  |             { | ||
|  |                  _logger.LogError("Falló la eliminación lógica de la Zona en el repositorio para el ID: {Id}", id); | ||
|  |                 return (false, "Error al eliminar la zona de la base de datos."); | ||
|  |             } | ||
|  |             return (true, null); // Éxito | ||
|  |         } | ||
|  |     } | ||
|  | } |