192 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			192 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | // 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; | ||
|  |     } | ||
|  | 
 | ||
|  |     // DTO para devolver los valores y su conteo | ||
|  |     public class ComponenteValorDto | ||
|  |     { | ||
|  |       public string Valor { get; set; } = ""; | ||
|  |       public int Conteo { get; set; } | ||
|  |     } | ||
|  | 
 | ||
|  |     [HttpGet("componentes/{tipo}")] | ||
|  |     public async Task<IActionResult> GetComponenteValores(string tipo) | ||
|  |     { | ||
|  |       var allowedTypes = new Dictionary<string, string> | ||
|  |             { | ||
|  |                 { "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<ComponenteValorDto>(query); | ||
|  |         return Ok(valores); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // DTO para la petición de unificación | ||
|  |     public class UnificarComponenteDto | ||
|  |     { | ||
|  |       public required string ValorNuevo { get; set; } | ||
|  |       public required string ValorAntiguo { get; set; } | ||
|  |     } | ||
|  | 
 | ||
|  |     [HttpPut("componentes/{tipo}/unificar")] | ||
|  |     public async Task<IActionResult> UnificarComponenteValores(string tipo, [FromBody] UnificarComponenteDto dto) | ||
|  |     { | ||
|  |       var allowedTypes = new Dictionary<string, string> | ||
|  |             { | ||
|  |                 { "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 }); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     // DTO para devolver los valores de RAM y su conteo | ||
|  |     public class RamMaestraDto | ||
|  |     { | ||
|  |       public int Id { get; set; } | ||
|  |       public string? Part_number { get; set; } | ||
|  |       public string? Fabricante { get; set; } | ||
|  |       public int Tamano { get; set; } | ||
|  |       public int? Velocidad { get; set; } | ||
|  |       public int Conteo { get; set; } | ||
|  |     } | ||
|  | 
 | ||
|  |     [HttpGet("componentes/ram")] | ||
|  |     public async Task<IActionResult> GetComponentesRam() | ||
|  |     { | ||
|  |       var query = @"
 | ||
|  |             SELECT | ||
|  |                 mr.Id, mr.part_number as PartNumber, 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.Id, mr.part_number, mr.Fabricante, mr.Tamano, mr.Velocidad | ||
|  |             ORDER BY | ||
|  |                 Conteo DESC, mr.Fabricante, mr.Tamano;";
 | ||
|  | 
 | ||
|  |       using (var connection = _context.CreateConnection()) | ||
|  |       { | ||
|  |         var valores = await connection.QueryAsync<RamMaestraDto>(query); | ||
|  |         return Ok(valores); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     [HttpDelete("componentes/ram/{id}")] | ||
|  |     public async Task<IActionResult> BorrarComponenteRam(int id) | ||
|  |     { | ||
|  |       using (var connection = _context.CreateConnection()) | ||
|  |       { | ||
|  |         // 1. Verificación de seguridad: Asegurarse de que el módulo no esté en uso. | ||
|  |         var usageQuery = "SELECT COUNT(*) FROM dbo.equipos_memorias_ram WHERE memoria_ram_id = @Id;"; | ||
|  |         var usageCount = await connection.ExecuteScalarAsync<int>(usageQuery, new { Id = id }); | ||
|  | 
 | ||
|  |         if (usageCount > 0) | ||
|  |         { | ||
|  |           return Conflict($"Este módulo de RAM está en uso por {usageCount} equipo(s) y no puede ser eliminado."); | ||
|  |         } | ||
|  | 
 | ||
|  |         // 2. Si no está en uso, proceder con la eliminación. | ||
|  |         var deleteQuery = "DELETE FROM dbo.memorias_ram WHERE Id = @Id;"; | ||
|  |         var filasAfectadas = await connection.ExecuteAsync(deleteQuery, new { Id = id }); | ||
|  | 
 | ||
|  |         if (filasAfectadas == 0) | ||
|  |         { | ||
|  |           return NotFound("Módulo de RAM no encontrado."); | ||
|  |         } | ||
|  | 
 | ||
|  |         return NoContent(); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     [HttpDelete("componentes/{tipo}/{valor}")] | ||
|  |     public async Task<IActionResult> BorrarComponenteTexto(string tipo, string valor) | ||
|  |     { | ||
|  |       var allowedTypes = new Dictionary<string, string> | ||
|  |         { | ||
|  |             { "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()) | ||
|  |       { | ||
|  |         // 1. Verificación de seguridad: Asegurarse de que el valor no esté en uso. | ||
|  |         var usageQuery = $"SELECT COUNT(*) FROM dbo.equipos WHERE {columnName} = @Valor;"; | ||
|  |         var usageCount = await connection.ExecuteScalarAsync<int>(usageQuery, new { Valor = valor }); | ||
|  | 
 | ||
|  |         if (usageCount > 0) | ||
|  |         { | ||
|  |           return Conflict($"Este valor está en uso por {usageCount} equipo(s) y no puede ser eliminado. Intente unificarlo en su lugar."); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Esta parte es más conceptual. Un componente de texto no existe en una tabla maestra, | ||
|  |         // por lo que no hay nada que "eliminar". El hecho de que el conteo sea 0 significa | ||
|  |         // que ya no existe en la práctica. Devolvemos éxito para confirmar esto. | ||
|  |         // Si tuviéramos tablas maestras (ej: dbo.sistemas_operativos), aquí iría la consulta DELETE. | ||
|  |         return NoContent(); | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | } |