Ya perdí el hilo de los cambios pero ahi van.
This commit is contained in:
173
Backend/GestionIntegral.Api/Services/Radios/CancionService.cs
Normal file
173
Backend/GestionIntegral.Api/Services/Radios/CancionService.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using GestionIntegral.Api.Data.Repositories.Radios;
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using GestionIntegral.Api.Models.Radios;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
// using GestionIntegral.Api.Data; // Para DbConnectionFactory si se usa transacción
|
||||
// using System.Data; // Para IsolationLevel si se usa transacción
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public class CancionService : ICancionService
|
||||
{
|
||||
private readonly ICancionRepository _cancionRepository;
|
||||
private readonly IRitmoRepository _ritmoRepository;
|
||||
private readonly ILogger<CancionService> _logger;
|
||||
|
||||
public CancionService(
|
||||
ICancionRepository cancionRepository,
|
||||
IRitmoRepository ritmoRepository,
|
||||
ILogger<CancionService> logger)
|
||||
{
|
||||
_cancionRepository = cancionRepository;
|
||||
_ritmoRepository = ritmoRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private async Task<CancionDto> MapToDto(Cancion cancion)
|
||||
{
|
||||
if (cancion == null) return null!;
|
||||
|
||||
string? nombreRitmo = null;
|
||||
if (cancion.Ritmo.HasValue && cancion.Ritmo.Value > 0)
|
||||
{
|
||||
var ritmoDb = await _ritmoRepository.GetByIdAsync(cancion.Ritmo.Value);
|
||||
nombreRitmo = ritmoDb?.NombreRitmo;
|
||||
}
|
||||
|
||||
return new CancionDto
|
||||
{
|
||||
Id = cancion.Id,
|
||||
Tema = cancion.Tema,
|
||||
CompositorAutor = cancion.CompositorAutor,
|
||||
Interprete = cancion.Interprete,
|
||||
Sello = cancion.Sello,
|
||||
Placa = cancion.Placa,
|
||||
Pista = cancion.Pista,
|
||||
Introduccion = cancion.Introduccion,
|
||||
IdRitmo = cancion.Ritmo, // Pasar el valor de cancion.Ritmo
|
||||
NombreRitmo = nombreRitmo,
|
||||
Formato = cancion.Formato,
|
||||
Album = cancion.Album
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<CancionDto>> ObtenerTodasAsync(string? temaFilter, string? interpreteFilter, int? idRitmoFilter)
|
||||
{
|
||||
var canciones = await _cancionRepository.GetAllAsync(temaFilter, interpreteFilter, idRitmoFilter);
|
||||
var dtos = new List<CancionDto>();
|
||||
foreach (var cancion in canciones)
|
||||
{
|
||||
dtos.Add(await MapToDto(cancion));
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<CancionDto?> ObtenerPorIdAsync(int id)
|
||||
{
|
||||
var cancion = await _cancionRepository.GetByIdAsync(id);
|
||||
return cancion == null ? null : await MapToDto(cancion);
|
||||
}
|
||||
|
||||
public async Task<(CancionDto? Cancion, string? Error)> CrearAsync(CreateCancionDto createDto, int idUsuario)
|
||||
{
|
||||
if (createDto.IdRitmo.HasValue && createDto.IdRitmo.Value > 0) // Asegurar que > 0 para evitar buscar ritmo con ID 0
|
||||
{
|
||||
if(await _ritmoRepository.GetByIdAsync(createDto.IdRitmo.Value) == null)
|
||||
return (null, "El ritmo seleccionado no es válido.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(createDto.Tema) && !string.IsNullOrWhiteSpace(createDto.Interprete) &&
|
||||
await _cancionRepository.ExistsByTemaAndInterpreteAsync(createDto.Tema, createDto.Interprete))
|
||||
{
|
||||
return (null, "Ya existe una canción con el mismo tema e intérprete.");
|
||||
}
|
||||
|
||||
var nuevaCancion = new Cancion
|
||||
{
|
||||
Tema = createDto.Tema, CompositorAutor = createDto.CompositorAutor, Interprete = createDto.Interprete,
|
||||
Sello = createDto.Sello, Placa = createDto.Placa, Pista = createDto.Pista,
|
||||
Introduccion = createDto.Introduccion,
|
||||
Ritmo = createDto.IdRitmo, // Asignar createDto.IdRitmo a la propiedad Ritmo del modelo
|
||||
Formato = createDto.Formato, Album = createDto.Album
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var cancionCreada = await _cancionRepository.CreateAsync(nuevaCancion);
|
||||
if (cancionCreada == null) return (null, "Error al crear la canción.");
|
||||
|
||||
_logger.LogInformation("Canción ID {Id} creada por Usuario ID {UserId}.", cancionCreada.Id, idUsuario);
|
||||
return (await MapToDto(cancionCreada), null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error CrearAsync Cancion: {Tema}", createDto.Tema);
|
||||
return (null, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateCancionDto updateDto, int idUsuario)
|
||||
{
|
||||
var cancionExistente = await _cancionRepository.GetByIdAsync(id);
|
||||
if (cancionExistente == null) return (false, "Canción no encontrada.");
|
||||
|
||||
if (updateDto.IdRitmo.HasValue && updateDto.IdRitmo.Value > 0) // Asegurar que > 0
|
||||
{
|
||||
if (await _ritmoRepository.GetByIdAsync(updateDto.IdRitmo.Value) == null)
|
||||
return (false, "El ritmo seleccionado no es válido.");
|
||||
}
|
||||
|
||||
|
||||
if ((!string.IsNullOrWhiteSpace(updateDto.Tema) && !string.IsNullOrWhiteSpace(updateDto.Interprete)) &&
|
||||
(cancionExistente.Tema != updateDto.Tema || cancionExistente.Interprete != updateDto.Interprete) &&
|
||||
await _cancionRepository.ExistsByTemaAndInterpreteAsync(updateDto.Tema!, updateDto.Interprete!, id))
|
||||
{
|
||||
return (false, "Ya existe otra canción con el mismo tema e intérprete."); // Devolver tupla bool,string
|
||||
}
|
||||
|
||||
cancionExistente.Tema = updateDto.Tema; cancionExistente.CompositorAutor = updateDto.CompositorAutor;
|
||||
cancionExistente.Interprete = updateDto.Interprete; cancionExistente.Sello = updateDto.Sello;
|
||||
cancionExistente.Placa = updateDto.Placa; cancionExistente.Pista = updateDto.Pista;
|
||||
cancionExistente.Introduccion = updateDto.Introduccion;
|
||||
cancionExistente.Ritmo = updateDto.IdRitmo; // Asignar updateDto.IdRitmo a la propiedad Ritmo del modelo
|
||||
cancionExistente.Formato = updateDto.Formato; cancionExistente.Album = updateDto.Album;
|
||||
|
||||
try
|
||||
{
|
||||
var actualizado = await _cancionRepository.UpdateAsync(cancionExistente);
|
||||
if (!actualizado) return (false, "Error al actualizar la canción.");
|
||||
|
||||
_logger.LogInformation("Canción ID {Id} actualizada por Usuario ID {UserId}.", id, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error ActualizarAsync Canción ID: {Id}", id);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario)
|
||||
{
|
||||
var cancionExistente = await _cancionRepository.GetByIdAsync(id);
|
||||
if (cancionExistente == null) return (false, "Canción no encontrada.");
|
||||
|
||||
try
|
||||
{
|
||||
var eliminado = await _cancionRepository.DeleteAsync(id);
|
||||
if (!eliminado) return (false, "Error al eliminar la canción.");
|
||||
|
||||
_logger.LogInformation("Canción ID {Id} eliminada por Usuario ID {UserId}.", id, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error EliminarAsync Canción ID: {Id}", id);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public interface ICancionService
|
||||
{
|
||||
Task<IEnumerable<CancionDto>> ObtenerTodasAsync(string? temaFilter, string? interpreteFilter, int? idRitmoFilter);
|
||||
Task<CancionDto?> ObtenerPorIdAsync(int id);
|
||||
Task<(CancionDto? Cancion, string? Error)> CrearAsync(CreateCancionDto createDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateCancionDto updateDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc; // Para IActionResult (o devolver byte[])
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public interface IRadioListaService
|
||||
{
|
||||
// Devuelve byte[] para el archivo y el nombre del archivo sugerido
|
||||
Task<(byte[] FileContents, string ContentType, string FileName, string? Error)> GenerarListaRadioAsync(GenerarListaRadioRequestDto request);
|
||||
}
|
||||
}
|
||||
15
Backend/GestionIntegral.Api/Services/Radios/IRitmoService.cs
Normal file
15
Backend/GestionIntegral.Api/Services/Radios/IRitmoService.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public interface IRitmoService
|
||||
{
|
||||
Task<IEnumerable<RitmoDto>> ObtenerTodosAsync(string? nombreFilter);
|
||||
Task<RitmoDto?> ObtenerPorIdAsync(int id);
|
||||
Task<(RitmoDto? Ritmo, string? Error)> CrearAsync(CreateRitmoDto createDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateRitmoDto updateDto, int idUsuario);
|
||||
Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario);
|
||||
}
|
||||
}
|
||||
224
Backend/GestionIntegral.Api/Services/Radios/RadioListaService.cs
Normal file
224
Backend/GestionIntegral.Api/Services/Radios/RadioListaService.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
using GestionIntegral.Api.Data.Repositories.Radios;
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using GestionIntegral.Api.Models.Radios; // Para Cancion
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NPOI.SS.UserModel;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public class RadioListaService : IRadioListaService
|
||||
{
|
||||
private readonly ICancionRepository _cancionRepository;
|
||||
// private readonly IRitmoRepository _ritmoRepository; // No se usa en la nueva lógica de generación de Excel
|
||||
private readonly ILogger<RadioListaService> _logger;
|
||||
|
||||
public RadioListaService(
|
||||
ICancionRepository cancionRepository,
|
||||
// IRitmoRepository ritmoRepository, // Puede ser removido si no se usa en otro lado
|
||||
ILogger<RadioListaService> logger)
|
||||
{
|
||||
_cancionRepository = cancionRepository;
|
||||
// _ritmoRepository = ritmoRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<(byte[] FileContents, string ContentType, string FileName, string? Error)> GenerarListaRadioAsync(GenerarListaRadioRequestDto request)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Iniciando generación de lista de radio para Mes: {Mes}, Año: {Anio}, Institución: {Institucion}, Radio: {Radio}",
|
||||
request.Mes, request.Anio, request.Institucion, request.Radio);
|
||||
|
||||
var programacionParaExcel = new List<ProgramacionHorariaExcelDto>();
|
||||
int diasEnMes = DateTime.DaysInMonth(request.Anio, request.Mes);
|
||||
|
||||
for (int dia = 1; dia <= diasEnMes; dia++)
|
||||
{
|
||||
int horaInicio = (request.Radio == "FM 99.1") ? 0 : 9;
|
||||
int horaFin = 23;
|
||||
|
||||
for (int hora = horaInicio; hora <= horaFin; hora++)
|
||||
{
|
||||
int cantidadRegistros;
|
||||
if (request.Radio == "FM 99.1")
|
||||
{
|
||||
cantidadRegistros = (hora == 23 || hora == 7 || hora == 15) ? 1 : 5;
|
||||
}
|
||||
else // FM 100.3
|
||||
{
|
||||
cantidadRegistros = (hora == 23 || hora == 15) ? 1 : 2;
|
||||
}
|
||||
|
||||
if (cantidadRegistros > 0)
|
||||
{
|
||||
var cancionesSeleccionadas = await _cancionRepository.GetRandomCancionesAsync(cantidadRegistros);
|
||||
foreach (var cancion in cancionesSeleccionadas)
|
||||
{
|
||||
programacionParaExcel.Add(new ProgramacionHorariaExcelDto
|
||||
{
|
||||
Dia = dia,
|
||||
Hora = hora,
|
||||
TituloObra = cancion.Tema,
|
||||
CompositorAutor = cancion.CompositorAutor,
|
||||
Interprete = cancion.Interprete,
|
||||
Sello = cancion.Sello,
|
||||
Album = cancion.Album
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!programacionParaExcel.Any())
|
||||
{
|
||||
_logger.LogWarning("No se generaron datos para la lista de radio con los criterios: {@Request}", request);
|
||||
return (Array.Empty<byte>(), "", "", "No se generaron datos para la lista con los criterios dados.");
|
||||
}
|
||||
|
||||
string mesText = request.Mes.ToString("00");
|
||||
string anioFullText = request.Anio.ToString();
|
||||
string anioShortText = anioFullText.Length > 2 ? anioFullText.Substring(anioFullText.Length - 2) : anioFullText;
|
||||
|
||||
byte[] excelBytes = GenerarExcel(programacionParaExcel, request.Institucion, request.Radio, mesText, anioFullText, anioShortText);
|
||||
|
||||
string baseFileName;
|
||||
if (request.Institucion == "AADI")
|
||||
{
|
||||
baseFileName = request.Radio == "FM 99.1" ? $"AADI-FM99.1-FM-{mesText}{anioShortText}" : $"AADI-FM100.3-FM-{mesText}{anioShortText}";
|
||||
}
|
||||
else // SADAIC
|
||||
{
|
||||
baseFileName = request.Radio == "FM 99.1" ? $"FM99.1-FM-{mesText}{anioShortText}" : $"FM100.3-FM-{mesText}{anioShortText}";
|
||||
}
|
||||
string excelFileNameInZip = $"{baseFileName}.xlsx";
|
||||
string zipFileName = $"{baseFileName}.xlsx.zip"; // Para replicar nombre original del zip
|
||||
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||
{
|
||||
var excelEntry = archive.CreateEntry(excelFileNameInZip, CompressionLevel.Optimal);
|
||||
using (var entryStream = excelEntry.Open())
|
||||
{
|
||||
await entryStream.WriteAsync(excelBytes, 0, excelBytes.Length);
|
||||
}
|
||||
}
|
||||
_logger.LogInformation("Lista de radio generada y empaquetada en ZIP exitosamente: {ZipFileName}", zipFileName);
|
||||
return (memoryStream.ToArray(), "application/zip", zipFileName, null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error al generar la lista de radio para Mes: {Mes}, Año: {Anio}, Institucion: {Institucion}, Radio: {Radio}", request.Mes, request.Anio, request.Institucion, request.Radio);
|
||||
return (Array.Empty<byte>(), "", "", $"Error interno al generar la lista: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GenerarExcel(List<ProgramacionHorariaExcelDto> programacion, string institucion, string radio, string mesText, string anioFullText, string anioShortText)
|
||||
{
|
||||
IWorkbook workbook = new XSSFWorkbook();
|
||||
|
||||
var coreProps = ((XSSFWorkbook)workbook).GetProperties().CoreProperties;
|
||||
coreProps.Creator = "GestionIntegral"; // Puedes cambiarlo
|
||||
coreProps.Title = $"Reporte {institucion} - {radio} - {mesText}/{anioFullText}";
|
||||
// coreProps.Description = "Descripción del reporte"; // Opcional
|
||||
// var extendedProps = ((XSSFWorkbook)workbook).GetProperties().ExtendedProperties.GetUnderlyingProperties();
|
||||
// extendedProps.Application = "GestionIntegral System"; // Opcional
|
||||
// extendedProps.AppVersion = "1.0.0"; // Opcional
|
||||
|
||||
string sheetName;
|
||||
if (institucion == "AADI")
|
||||
{
|
||||
sheetName = radio == "FM 99.1" ? $"SA99{mesText}{anioShortText}" : $"SARE{mesText}{anioShortText}";
|
||||
}
|
||||
else // SADAIC
|
||||
{
|
||||
sheetName = radio == "FM 99.1" ? $"FM99{mesText}{anioShortText}" : $"FMRE{mesText}{anioShortText}";
|
||||
}
|
||||
ISheet sheet = workbook.CreateSheet(sheetName);
|
||||
|
||||
int currentRowIdx = 0;
|
||||
if (institucion == "AADI")
|
||||
{
|
||||
sheet.CreateRow(currentRowIdx++).CreateCell(0).SetCellValue(radio == "FM 99.1" ? "Nombre: FM LA 99.1" : "Nombre: FM 100.3 LA REDONDA");
|
||||
sheet.CreateRow(currentRowIdx++).CreateCell(0).SetCellValue("Localidad: La Plata");
|
||||
sheet.CreateRow(currentRowIdx++).CreateCell(0).SetCellValue("FM");
|
||||
sheet.CreateRow(currentRowIdx++).CreateCell(0).SetCellValue(radio == "FM 99.1" ? "Frecuencia: 99.1" : "Frecuencia: 100.3");
|
||||
sheet.CreateRow(currentRowIdx++).CreateCell(0).SetCellValue($"Mes: {mesText}/{anioFullText}");
|
||||
}
|
||||
|
||||
IRow headerDataRow = sheet.CreateRow(currentRowIdx++);
|
||||
headerDataRow.CreateCell(0).SetCellValue("Día");
|
||||
headerDataRow.CreateCell(1).SetCellValue("Hora");
|
||||
headerDataRow.CreateCell(2).SetCellValue("Título de la Obra");
|
||||
headerDataRow.CreateCell(3).SetCellValue("Compositor-Autor");
|
||||
headerDataRow.CreateCell(4).SetCellValue("Intérprete");
|
||||
headerDataRow.CreateCell(5).SetCellValue("Sello");
|
||||
headerDataRow.CreateCell(6).SetCellValue("Álbum");
|
||||
|
||||
IFont font = workbook.CreateFont();
|
||||
font.FontHeightInPoints = 10;
|
||||
font.FontName = "Arial";
|
||||
ICellStyle cellStyle = workbook.CreateCellStyle();
|
||||
cellStyle.SetFont(font);
|
||||
|
||||
foreach (var item in programacion)
|
||||
{
|
||||
IRow dataRow = sheet.CreateRow(currentRowIdx++);
|
||||
dataRow.CreateCell(0).SetCellValue(item.Dia);
|
||||
dataRow.CreateCell(1).SetCellValue(item.Hora);
|
||||
dataRow.CreateCell(2).SetCellValue(item.TituloObra);
|
||||
dataRow.CreateCell(3).SetCellValue(item.CompositorAutor);
|
||||
dataRow.CreateCell(4).SetCellValue(item.Interprete);
|
||||
dataRow.CreateCell(5).SetCellValue(item.Sello);
|
||||
dataRow.CreateCell(6).SetCellValue(item.Album);
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
ICell cell = dataRow.GetCell(i) ?? dataRow.CreateCell(i); // Asegurarse que la celda exista
|
||||
cell.CellStyle = cellStyle;
|
||||
}
|
||||
}
|
||||
|
||||
sheet.SetColumnWidth(0, 4 * 256);
|
||||
sheet.SetColumnWidth(1, 5 * 256);
|
||||
sheet.SetColumnWidth(2, 25 * 256);
|
||||
sheet.SetColumnWidth(3, 14 * 256);
|
||||
sheet.SetColumnWidth(4, 11 * 256);
|
||||
sheet.SetColumnWidth(5, 11 * 256);
|
||||
sheet.SetColumnWidth(6, 30 * 256);
|
||||
|
||||
short rowHeight = 255; // 12.75 puntos
|
||||
for (int i = 0; i < currentRowIdx; i++)
|
||||
{
|
||||
IRow row = sheet.GetRow(i) ?? sheet.CreateRow(i);
|
||||
row.Height = rowHeight;
|
||||
|
||||
// Aplicar estilo a todas las celdas de las filas de encabezado también
|
||||
if (i < (institucion == "AADI" ? 5 : 0) || i == (institucion == "AADI" ? 5 : 0)) // Filas de cabecera de AADI o la fila de títulos de columnas
|
||||
{
|
||||
// Iterar sobre las celdas que realmente existen o deberían existir
|
||||
int lastCellNum = (institucion == "AADI" && i < 5) ? 1 : 7; // Cabecera AADI solo tiene 1 celda, títulos de datos tienen 7
|
||||
for (int j = 0; j < lastCellNum; j++)
|
||||
{
|
||||
ICell cell = row.GetCell(j) ?? row.CreateCell(j);
|
||||
cell.CellStyle = cellStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
workbook.Write(memoryStream, true); // El 'true' es para dejar el stream abierto si se necesita
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
133
Backend/GestionIntegral.Api/Services/Radios/RitmoService.cs
Normal file
133
Backend/GestionIntegral.Api/Services/Radios/RitmoService.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using GestionIntegral.Api.Data.Repositories.Radios;
|
||||
using GestionIntegral.Api.Dtos.Radios;
|
||||
using GestionIntegral.Api.Models.Radios;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
// using GestionIntegral.Api.Data; // Para DbConnectionFactory si se usa transacción
|
||||
// using System.Data; // Para IsolationLevel si se usa transacción
|
||||
|
||||
namespace GestionIntegral.Api.Services.Radios
|
||||
{
|
||||
public class RitmoService : IRitmoService
|
||||
{
|
||||
private readonly IRitmoRepository _ritmoRepository;
|
||||
private readonly ILogger<RitmoService> _logger;
|
||||
// private readonly DbConnectionFactory _connectionFactory; // Si se implementa historial
|
||||
|
||||
public RitmoService(IRitmoRepository ritmoRepository, ILogger<RitmoService> logger /*, DbConnectionFactory cf */)
|
||||
{
|
||||
_ritmoRepository = ritmoRepository;
|
||||
_logger = logger;
|
||||
// _connectionFactory = cf;
|
||||
}
|
||||
|
||||
private RitmoDto MapToDto(Ritmo ritmo) => new RitmoDto
|
||||
{
|
||||
Id = ritmo.Id,
|
||||
NombreRitmo = ritmo.NombreRitmo
|
||||
};
|
||||
|
||||
public async Task<IEnumerable<RitmoDto>> ObtenerTodosAsync(string? nombreFilter)
|
||||
{
|
||||
var ritmos = await _ritmoRepository.GetAllAsync(nombreFilter);
|
||||
return ritmos.Select(MapToDto);
|
||||
}
|
||||
|
||||
public async Task<RitmoDto?> ObtenerPorIdAsync(int id)
|
||||
{
|
||||
var ritmo = await _ritmoRepository.GetByIdAsync(id);
|
||||
return ritmo == null ? null : MapToDto(ritmo);
|
||||
}
|
||||
|
||||
public async Task<(RitmoDto? Ritmo, string? Error)> CrearAsync(CreateRitmoDto createDto, int idUsuario)
|
||||
{
|
||||
if (await _ritmoRepository.ExistsByNameAsync(createDto.NombreRitmo))
|
||||
{
|
||||
return (null, "El nombre del ritmo ya existe.");
|
||||
}
|
||||
|
||||
var nuevoRitmo = new Ritmo { NombreRitmo = createDto.NombreRitmo };
|
||||
|
||||
// Sin historial, la transacción es opcional para una sola operación,
|
||||
// pero se deja la estructura por si se añade más lógica o historial.
|
||||
// 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 ritmoCreado = await _ritmoRepository.CreateAsync(nuevoRitmo /*, idUsuario, transaction */);
|
||||
if (ritmoCreado == null) return (null, "Error al crear el ritmo.");
|
||||
|
||||
// transaction.Commit();
|
||||
_logger.LogInformation("Ritmo ID {Id} creado por Usuario ID {UserId}.", ritmoCreado.Id, idUsuario);
|
||||
return (MapToDto(ritmoCreado), null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// try { transaction.Rollback(); } catch {}
|
||||
_logger.LogError(ex, "Error CrearAsync Ritmo: {NombreRitmo}", createDto.NombreRitmo);
|
||||
return (null, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> ActualizarAsync(int id, UpdateRitmoDto updateDto, int idUsuario)
|
||||
{
|
||||
var ritmoExistente = await _ritmoRepository.GetByIdAsync(id);
|
||||
if (ritmoExistente == null) return (false, "Ritmo no encontrado.");
|
||||
|
||||
if (ritmoExistente.NombreRitmo != updateDto.NombreRitmo && await _ritmoRepository.ExistsByNameAsync(updateDto.NombreRitmo, id))
|
||||
{
|
||||
return (false, "El nombre del ritmo ya existe para otro registro.");
|
||||
}
|
||||
|
||||
ritmoExistente.NombreRitmo = updateDto.NombreRitmo;
|
||||
|
||||
// Sin historial, la transacción es opcional...
|
||||
try
|
||||
{
|
||||
var actualizado = await _ritmoRepository.UpdateAsync(ritmoExistente /*, idUsuario, transaction */);
|
||||
if (!actualizado) return (false, "Error al actualizar el ritmo.");
|
||||
|
||||
// transaction.Commit();
|
||||
_logger.LogInformation("Ritmo ID {Id} actualizado por Usuario ID {UserId}.", id, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// try { transaction.Rollback(); } catch {}
|
||||
_logger.LogError(ex, "Error ActualizarAsync Ritmo ID: {Id}", id);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<(bool Exito, string? Error)> EliminarAsync(int id, int idUsuario)
|
||||
{
|
||||
var ritmoExistente = await _ritmoRepository.GetByIdAsync(id);
|
||||
if (ritmoExistente == null) return (false, "Ritmo no encontrado.");
|
||||
|
||||
if (await _ritmoRepository.IsInUseAsync(id))
|
||||
{
|
||||
return (false, "No se puede eliminar. El ritmo está asignado a una o más canciones.");
|
||||
}
|
||||
|
||||
// Sin historial, la transacción es opcional...
|
||||
try
|
||||
{
|
||||
var eliminado = await _ritmoRepository.DeleteAsync(id /*, idUsuario, transaction */);
|
||||
if (!eliminado) return (false, "Error al eliminar el ritmo.");
|
||||
|
||||
// transaction.Commit();
|
||||
_logger.LogInformation("Ritmo ID {Id} eliminado por Usuario ID {UserId}.", id, idUsuario);
|
||||
return (true, null);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// try { transaction.Rollback(); } catch {}
|
||||
_logger.LogError(ex, "Error EliminarAsync Ritmo ID: {Id}", id);
|
||||
return (false, $"Error interno: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user