< Summary

Information
Class: FAU.Logica.Services.AguinaldoHistoricoService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/AguinaldoHistoricoService.cs
Line coverage
100%
Covered lines: 86
Uncovered lines: 0
Coverable lines: 86
Total lines: 144
Line coverage: 100%
Branch coverage
88%
Covered branches: 23
Total branches: 26
Branch coverage: 88.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
CompletarHistoricoAsync()95%2020100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/AguinaldoHistoricoService.cs

#LineLine coverage
 1using FAU.DataAccess;
 2using FAU.Entidades;
 3using FAU.Logica.DTOs;
 4using Microsoft.EntityFrameworkCore;
 5
 6namespace FAU.Logica.Services;
 7
 8public class AguinaldoHistoricoService : IAguinaldoHistoricoService
 9{
 10    private readonly ApplicationDbContext _context;
 11
 612    public AguinaldoHistoricoService(ApplicationDbContext context)
 13    {
 614        _context = context;
 615    }
 16
 17    public async Task<CompletarHistoricoAguinaldoResultadoDto> CompletarHistoricoAsync(
 18        CompletarHistoricoAguinaldoRequest request)
 19    {
 620        var resultado = new CompletarHistoricoAguinaldoResultadoDto();
 21
 1322        var cedulasRequeridas = request.Funcionarios.Select(f => f.Cedula).Distinct().ToList();
 23
 24        // Cédula → persona_id
 625        var personasPorCedula = await _context.Personas
 626            .Where(p => cedulasRequeridas.Contains(p.Cedula))
 627            .Select(p => new { p.Cedula, p.Id })
 1628            .ToDictionaryAsync(p => p.Cedula, p => p.Id);
 29
 630        var personaIds = personasPorCedula.Values.ToList();
 31
 32        // Cargar TODAS las relaciones laborales de esas personas (activas e inactivas)
 33        // para poder buscar cuál estaba vigente en cada mes/año
 634        var todasRelaciones = await _context.RelacionesLaborales
 635            .Where(rl => personaIds.Contains(rl.PersonaId))
 636            .ToListAsync();
 37
 638        var relacionesPorPersona = todasRelaciones
 539            .GroupBy(rl => rl.PersonaId)
 640            .ToDictionary(
 541                g => g.Key,
 1642                g => g.OrderByDescending(rl => rl.FechaInicio).ToList());
 43
 44        // Cargar registros existentes en historico para upsert
 645        var aniosRequeridos = request.Funcionarios
 2146            .SelectMany(f => f.Meses).Select(m => (short)m.Anio).Distinct().ToList();
 647        var mesesRequeridos = request.Funcionarios
 2148            .SelectMany(f => f.Meses).Select(m => (short)m.Mes).Distinct().ToList();
 49
 650        var existentes = await _context.HistoricoLiquidaciones
 651            .Where(h => personaIds.Contains(h.PersonaId)
 652                && aniosRequeridos.Contains(h.Anio)
 653                && mesesRequeridos.Contains(h.Mes))
 654            .ToListAsync();
 55
 656        var existentesPorKey = existentes
 757            .ToDictionary(h => (h.PersonaId, h.Anio, h.Mes));
 58
 2659        foreach (var funcionario in request.Funcionarios)
 60        {
 761            if (!personasPorCedula.TryGetValue(funcionario.Cedula, out var personaId))
 62            {
 863                foreach (var mesItem in funcionario.Meses)
 64                {
 265                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 266                    {
 267                        Cedula = funcionario.Cedula,
 268                        Anio = mesItem.Anio,
 269                        Mes = mesItem.Mes,
 270                        Descripcion = $"No se encontró persona con cédula {funcionario.Cedula}."
 271                    });
 72                }
 73                continue;
 74            }
 75
 576            var relacionesFuncionario = relacionesPorPersona.GetValueOrDefault(personaId)
 577                ?? new List<RelacionLaboral>();
 78
 2279            foreach (var mesItem in funcionario.Meses)
 80            {
 681                if (mesItem.Monto <= 0)
 82                {
 283                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 284                    {
 285                        Cedula = funcionario.Cedula,
 286                        Anio = mesItem.Anio,
 287                        Mes = mesItem.Mes,
 288                        Descripcion = "El monto debe ser mayor a cero."
 289                    });
 290                    continue;
 91                }
 92
 93                // Buscar la relación laboral vigente durante ese mes/año.
 94                // Vigente = fecha_inicio <= último día del mes Y (fecha_fin IS NULL O fecha_fin >= primer día del mes)
 495                var primerDia  = new DateTime(mesItem.Anio, mesItem.Mes, 1);
 496                var ultimoDia  = primerDia.AddMonths(1).AddDays(-1);
 97
 498                var relacion = relacionesFuncionario
 499                    .FirstOrDefault(rl =>
 8100                        rl.FechaInicio <= ultimoDia &&
 8101                        (rl.FechaFin == null || rl.FechaFin >= primerDia));
 102
 4103                if (relacion == null)
 104                {
 1105                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 1106                    {
 1107                        Cedula = funcionario.Cedula,
 1108                        Anio = mesItem.Anio,
 1109                        Mes = mesItem.Mes,
 1110                        Descripcion = $"No se encontró relación laboral vigente en {mesItem.Mes:D2}/{mesItem.Anio} para 
 1111                    });
 1112                    continue;
 113                }
 114
 3115                var key = (personaId, (short)mesItem.Anio, (short)mesItem.Mes);
 3116                if (existentesPorKey.TryGetValue(key, out var existente))
 117                {
 1118                    existente.HaberesGravados = mesItem.Monto;
 1119                    resultado.ItemsActualizados++;
 120                }
 121                else
 122                {
 2123                    var nuevo = new HistoricoLiquidacion
 2124                    {
 2125                        PersonaId       = personaId,
 2126                        Anio            = (short)mesItem.Anio,
 2127                        Mes             = (short)mesItem.Mes,
 2128                        HaberesGravados = mesItem.Monto,
 2129                        Origen          = "MANUAL",
 2130                        FechaCreacion   = DateTime.UtcNow
 2131                    };
 2132                    _context.HistoricoLiquidaciones.Add(nuevo);
 2133                    existentesPorKey[key] = nuevo;
 2134                    resultado.ItemsGuardados++;
 135                }
 136            }
 137        }
 138
 6139        if (resultado.ItemsGuardados > 0 || resultado.ItemsActualizados > 0)
 3140            await _context.SaveChangesAsync();
 141
 6142        return resultado;
 6143    }
 144}