< 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
0%
Covered lines: 0
Uncovered lines: 86
Coverable lines: 86
Total lines: 144
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 26
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
CompletarHistoricoAsync()0%420200%

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
 012    public AguinaldoHistoricoService(ApplicationDbContext context)
 13    {
 014        _context = context;
 015    }
 16
 17    public async Task<CompletarHistoricoAguinaldoResultadoDto> CompletarHistoricoAsync(
 18        CompletarHistoricoAguinaldoRequest request)
 19    {
 020        var resultado = new CompletarHistoricoAguinaldoResultadoDto();
 21
 022        var cedulasRequeridas = request.Funcionarios.Select(f => f.Cedula).Distinct().ToList();
 23
 24        // Cédula → persona_id
 025        var personasPorCedula = await _context.Personas
 026            .Where(p => cedulasRequeridas.Contains(p.Cedula))
 027            .Select(p => new { p.Cedula, p.Id })
 028            .ToDictionaryAsync(p => p.Cedula, p => p.Id);
 29
 030        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
 034        var todasRelaciones = await _context.RelacionesLaborales
 035            .Where(rl => personaIds.Contains(rl.PersonaId))
 036            .ToListAsync();
 37
 038        var relacionesPorPersona = todasRelaciones
 039            .GroupBy(rl => rl.PersonaId)
 040            .ToDictionary(
 041                g => g.Key,
 042                g => g.OrderByDescending(rl => rl.FechaInicio).ToList());
 43
 44        // Cargar registros existentes en historico para upsert
 045        var aniosRequeridos = request.Funcionarios
 046            .SelectMany(f => f.Meses).Select(m => (short)m.Anio).Distinct().ToList();
 047        var mesesRequeridos = request.Funcionarios
 048            .SelectMany(f => f.Meses).Select(m => (short)m.Mes).Distinct().ToList();
 49
 050        var existentes = await _context.HistoricoLiquidaciones
 051            .Where(h => personaIds.Contains(h.PersonaId)
 052                && aniosRequeridos.Contains(h.Anio)
 053                && mesesRequeridos.Contains(h.Mes))
 054            .ToListAsync();
 55
 056        var existentesPorKey = existentes
 057            .ToDictionary(h => (h.PersonaId, h.Anio, h.Mes));
 58
 059        foreach (var funcionario in request.Funcionarios)
 60        {
 061            if (!personasPorCedula.TryGetValue(funcionario.Cedula, out var personaId))
 62            {
 063                foreach (var mesItem in funcionario.Meses)
 64                {
 065                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 066                    {
 067                        Cedula = funcionario.Cedula,
 068                        Anio = mesItem.Anio,
 069                        Mes = mesItem.Mes,
 070                        Descripcion = $"No se encontró persona con cédula {funcionario.Cedula}."
 071                    });
 72                }
 73                continue;
 74            }
 75
 076            var relacionesFuncionario = relacionesPorPersona.GetValueOrDefault(personaId)
 077                ?? new List<RelacionLaboral>();
 78
 079            foreach (var mesItem in funcionario.Meses)
 80            {
 081                if (mesItem.Monto <= 0)
 82                {
 083                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 084                    {
 085                        Cedula = funcionario.Cedula,
 086                        Anio = mesItem.Anio,
 087                        Mes = mesItem.Mes,
 088                        Descripcion = "El monto debe ser mayor a cero."
 089                    });
 090                    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)
 095                var primerDia  = new DateTime(mesItem.Anio, mesItem.Mes, 1);
 096                var ultimoDia  = primerDia.AddMonths(1).AddDays(-1);
 97
 098                var relacion = relacionesFuncionario
 099                    .FirstOrDefault(rl =>
 0100                        rl.FechaInicio <= ultimoDia &&
 0101                        (rl.FechaFin == null || rl.FechaFin >= primerDia));
 102
 0103                if (relacion == null)
 104                {
 0105                    resultado.Errores.Add(new CompletarHistoricoErrorDto
 0106                    {
 0107                        Cedula = funcionario.Cedula,
 0108                        Anio = mesItem.Anio,
 0109                        Mes = mesItem.Mes,
 0110                        Descripcion = $"No se encontró relación laboral vigente en {mesItem.Mes:D2}/{mesItem.Anio} para 
 0111                    });
 0112                    continue;
 113                }
 114
 0115                var key = (personaId, (short)mesItem.Anio, (short)mesItem.Mes);
 0116                if (existentesPorKey.TryGetValue(key, out var existente))
 117                {
 0118                    existente.HaberesGravados = mesItem.Monto;
 0119                    resultado.ItemsActualizados++;
 120                }
 121                else
 122                {
 0123                    var nuevo = new HistoricoLiquidacion
 0124                    {
 0125                        PersonaId       = personaId,
 0126                        Anio            = (short)mesItem.Anio,
 0127                        Mes             = (short)mesItem.Mes,
 0128                        HaberesGravados = mesItem.Monto,
 0129                        Origen          = "MANUAL",
 0130                        FechaCreacion   = DateTime.UtcNow
 0131                    };
 0132                    _context.HistoricoLiquidaciones.Add(nuevo);
 0133                    existentesPorKey[key] = nuevo;
 0134                    resultado.ItemsGuardados++;
 135                }
 136            }
 137        }
 138
 0139        if (resultado.ItemsGuardados > 0 || resultado.ItemsActualizados > 0)
 0140            await _context.SaveChangesAsync();
 141
 0142        return resultado;
 0143    }
 144}