// backend/Controllers/AdminController.cs using Dapper; using Inventario.API.Data; using Microsoft.AspNetCore.Mvc; namespace Inventario.API.Controllers { [ApiController] [Route("api/[controller]")] public class AdminController : ControllerBase { private readonly DapperContext _context; public AdminController(DapperContext context) { _context = context; } // --- DTOs para los componentes --- public class ComponenteValorDto { public string Valor { get; set; } = ""; public int Conteo { get; set; } } public class UnificarComponenteDto { public required string ValorNuevo { get; set; } public required string ValorAntiguo { get; set; } } public class RamAgrupadaDto { public string? Fabricante { get; set; } public int Tamano { get; set; } public int? Velocidad { get; set; } public int Conteo { get; set; } } public class BorrarRamAgrupadaDto { public string? Fabricante { get; set; } public int Tamano { get; set; } public int? Velocidad { get; set; } } [HttpGet("componentes/{tipo}")] public async Task GetComponenteValores(string tipo) { var allowedTypes = new Dictionary { { "os", "Os" }, { "cpu", "Cpu" }, { "motherboard", "Motherboard" }, { "architecture", "Architecture" } }; if (!allowedTypes.TryGetValue(tipo.ToLower(), out var columnName)) { return BadRequest("Tipo de componente no válido."); } var query = $@" SELECT {columnName} AS Valor, COUNT(*) AS Conteo FROM dbo.equipos WHERE {columnName} IS NOT NULL AND {columnName} != '' GROUP BY {columnName} ORDER BY Conteo DESC, Valor ASC;"; using (var connection = _context.CreateConnection()) { var valores = await connection.QueryAsync(query); return Ok(valores); } } [HttpPut("componentes/{tipo}/unificar")] public async Task UnificarComponenteValores(string tipo, [FromBody] UnificarComponenteDto dto) { var allowedTypes = new Dictionary { { "os", "Os" }, { "cpu", "Cpu" }, { "motherboard", "Motherboard" }, { "architecture", "Architecture" } }; if (!allowedTypes.TryGetValue(tipo.ToLower(), out var columnName)) { return BadRequest("Tipo de componente no válido."); } if (dto.ValorAntiguo == dto.ValorNuevo) { return BadRequest("El valor antiguo y el nuevo no pueden ser iguales."); } var query = $@" UPDATE dbo.equipos SET {columnName} = @ValorNuevo WHERE {columnName} = @ValorAntiguo;"; using (var connection = _context.CreateConnection()) { var filasAfectadas = await connection.ExecuteAsync(query, new { dto.ValorNuevo, dto.ValorAntiguo }); return Ok(new { message = $"Se unificaron {filasAfectadas} registros.", filasAfectadas }); } } // --- Devuelve la RAM agrupada --- [HttpGet("componentes/ram")] public async Task GetComponentesRam() { var query = @" SELECT mr.Fabricante, mr.Tamano, mr.Velocidad, COUNT(emr.memoria_ram_id) as Conteo FROM dbo.memorias_ram mr LEFT JOIN dbo.equipos_memorias_ram emr ON mr.id = emr.memoria_ram_id GROUP BY mr.Fabricante, mr.Tamano, mr.Velocidad ORDER BY Conteo DESC, mr.Fabricante, mr.Tamano;"; using (var connection = _context.CreateConnection()) { var valores = await connection.QueryAsync(query); return Ok(valores); } } // --- Elimina un grupo completo --- [HttpDelete("componentes/ram")] public async Task BorrarComponenteRam([FromBody] BorrarRamAgrupadaDto dto) { using (var connection = _context.CreateConnection()) { // Verificación de seguridad: Asegurarse de que el grupo no esté en uso. var usageQuery = @" SELECT COUNT(emr.id) FROM dbo.memorias_ram mr LEFT JOIN dbo.equipos_memorias_ram emr ON mr.id = emr.memoria_ram_id WHERE (mr.Fabricante = @Fabricante OR (mr.Fabricante IS NULL AND @Fabricante IS NULL)) AND mr.Tamano = @Tamano AND (mr.Velocidad = @Velocidad OR (mr.Velocidad IS NULL AND @Velocidad IS NULL));"; var usageCount = await connection.ExecuteScalarAsync(usageQuery, dto); if (usageCount > 0) { return Conflict(new { message = $"Este grupo de RAM está en uso por {usageCount} equipo(s) y no puede ser eliminado." }); } // Si no está en uso, proceder con la eliminación de todos los registros maestros que coincidan. var deleteQuery = @" DELETE FROM dbo.memorias_ram WHERE (Fabricante = @Fabricante OR (Fabricante IS NULL AND @Fabricante IS NULL)) AND Tamano = @Tamano AND (Velocidad = @Velocidad OR (Velocidad IS NULL AND @Velocidad IS NULL));"; await connection.ExecuteAsync(deleteQuery, dto); return NoContent(); } } [HttpDelete("componentes/{tipo}/{valor}")] public async Task BorrarComponenteTexto(string tipo, string valor) { var allowedTypes = new Dictionary { { "os", "Os" }, { "cpu", "Cpu" }, { "motherboard", "Motherboard" }, { "architecture", "Architecture" } }; if (!allowedTypes.TryGetValue(tipo.ToLower(), out var columnName)) { return BadRequest("Tipo de componente no válido."); } using (var connection = _context.CreateConnection()) { var usageQuery = $"SELECT COUNT(*) FROM dbo.equipos WHERE {columnName} = @Valor;"; var usageCount = await connection.ExecuteScalarAsync(usageQuery, new { Valor = valor }); if (usageCount > 0) { return Conflict(new { message = $"Este valor está en uso por {usageCount} equipo(s) y no puede ser eliminado. Intente unificarlo en su lugar." }); } return NoContent(); } } } }