< Summary

Information
Class: FAU.Logica.Services.InsumosPeriodoLoader
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/InsumosPeriodoLoader.cs
Line coverage
90%
Covered lines: 199
Uncovered lines: 22
Coverable lines: 221
Total lines: 293
Line coverage: 90%
Branch coverage
38%
Covered branches: 7
Total branches: 18
Branch coverage: 38.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
CargarAsync()60%101098.13%

File(s)

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

#LineLine coverage
 1using FAU.DataAccess;
 2using FAU.Entidades;
 3using FAU.Logica.DTOs;
 4using Microsoft.EntityFrameworkCore;
 5
 6namespace FAU.Logica.Services;
 7
 8public class InsumosPeriodoLoader : IInsumosPeriodoLoader
 9{
 10    private readonly ApplicationDbContext _context;
 11
 1612    public InsumosPeriodoLoader(ApplicationDbContext context)
 13    {
 1614        _context = context;
 1615    }
 16
 17    public async Task<InsumosPeriodo> CargarAsync(long periodoId)
 18    {
 1619        var periodo = await _context.PeriodosLiquidacion
 1620            .AsNoTracking()
 1621            .FirstOrDefaultAsync(p => p.Id == periodoId && p.Activo);
 22
 1623        if (periodo is null)
 24        {
 025            throw new InvalidOperationException($"Periodo de liquidación {periodoId} no encontrado o no está activo.");
 26        }
 27
 1628        var periodoDate = new DateTime(periodo.Anio, periodo.Mes, 1);
 1629        var ultimoDiaPeriodo = new DateTime(periodo.Anio, periodo.Mes, DateTime.DaysInMonth(periodo.Anio, periodo.Mes));
 30
 1631        var parametros = await _context.ParametrosPeriodo
 1632            .AsNoTracking()
 1633            .Where(pp => pp.Anio < periodo.Anio || (pp.Anio == periodo.Anio && pp.Mes <= periodo.Mes))
 1634            .OrderByDescending(pp => pp.Anio)
 1635            .ThenByDescending(pp => pp.Mes)
 1636            .FirstOrDefaultAsync();
 37
 1638        if (parametros is null)
 39        {
 040            throw new InvalidOperationException($"No hay parámetros de período configurados para {periodo.Anio}/{periodo
 41        }
 42
 1643        var catalogoItems = await _context.CatalogoItems
 1644            .AsNoTracking()
 1645            .ToListAsync();
 46
 1647        var remuneraciones = await _context.RemuneracionesGrado
 1648            .AsNoTracking()
 1649            .Include(r => r.Item)
 1650            .Where(r => r.VigenteDesde <= periodoDate && (r.VigenteHasta == null || r.VigenteHasta >= periodoDate))
 1651            .ToListAsync();
 52
 1653        var tarifasCategoria = await _context.TarifasPorCategoria
 1654            .AsNoTracking()
 1655            .Include(t => t.Item)
 1656            .Where(t => t.VigenteDesde <= periodoDate && (t.VigenteHasta == null || t.VigenteHasta >= periodoDate))
 1657            .ToListAsync();
 58
 1659        var compPersonal048018 = await _context.CompPersonal048018
 1660            .AsNoTracking()
 1661            .Where(c => c.Estado == "activo"
 1662                     && c.VigenteDesde <= periodoDate && (c.VigenteHasta == null || c.VigenteHasta >= periodoDate))
 1663            .ToListAsync();
 64
 1665        var permanencias = await _context.Set<TablaPermanencia>()
 1666            .AsNoTracking()
 1667            .Where(t => t.Activo)
 1668            .Where(t => t.VigenteDesde <= periodoDate && (t.VigenteHasta == null || t.VigenteHasta >= periodoDate))
 1669            .ToListAsync();
 70
 1671        var franjasIrpfRaw = await _context.FranjasIrpf
 1672            .AsNoTracking()
 1673            .Where(f => f.VigenteDesde <= periodoDate && (f.VigenteHasta == null || f.VigenteHasta >= periodoDate))
 1674            .ToListAsync();
 75
 76        // Deduplicar: una franja por NumeroFranja, la más reciente según VigenteDesde
 1677        var franjasIrpf = franjasIrpfRaw
 3278            .GroupBy(f => f.NumeroFranja)
 6479            .Select(g => g.OrderByDescending(f => f.VigenteDesde).First())
 3280            .OrderBy(f => f.NumeroFranja)
 1681            .ToList();
 82
 83        // Tramos de Sanidad Militar vigentes (Art. 94 Ley 18.834)
 1684        var tramosSanidadRaw = await _context.TramosSanidadMilitar
 1685            .AsNoTracking()
 1686            .Where(t => t.VigenteDesde <= periodoDate && (t.VigenteHasta == null || t.VigenteHasta >= periodoDate))
 1687            .ToListAsync();
 88
 89        // Deduplicar por código de retención, el más reciente según VigenteDesde; ordenar por Desde
 1690        var tramosSanidad = tramosSanidadRaw
 091            .GroupBy(t => t.CodigoRetencion)
 092            .Select(g => g.OrderByDescending(t => t.VigenteDesde).First())
 093            .OrderBy(t => t.Desde)
 1694            .ToList();
 95
 1696        var beneficios = await _context.BeneficiosSociales
 1697            .AsNoTracking()
 1698            .Where(b => b.Estado == "activo"
 1699                     && b.VigenteDesde <= ultimoDiaPeriodo          // inició antes del fin del período
 16100                     && (b.VigenteHasta == null || b.VigenteHasta >= periodoDate))  // no terminó antes del inicio
 16101            .ToListAsync();
 102
 16103        var tiposBeneficio = await _context.TiposBeneficio
 16104            .AsNoTracking()
 16105            .ToDictionaryAsync(t => t.Id);
 106
 34107        foreach (var b in beneficios)
 108        {
 1109            if (tiposBeneficio.TryGetValue(b.TipoBeneficioId, out var tipo))
 0110                b.TipoBeneficio = tipo;
 111        }
 112
 113        // Cargar hijos registrados para beneficios de tipo Asignación Familiar
 16114        var idsAsigFamiliar = beneficios
 1115            .Where(b => b.TipoBeneficio is not null &&
 1116                        (b.TipoBeneficio.Codigo == "ASIGNACION_FAMILIAR" ||
 1117                         b.TipoBeneficio.Codigo.StartsWith("300") ||
 1118                         b.TipoBeneficio.Nombre.ToUpperInvariant().Contains("ASIGNACION FAMILIAR") ||
 1119                         b.TipoBeneficio.Nombre.ToUpperInvariant().Contains("ASIGNACIÓN FAMILIAR")))
 0120            .Select(b => b.Id)
 16121            .ToHashSet();
 122
 16123        var beneficiariosAsigFam = idsAsigFamiliar.Count > 0
 16124            ? await _context.BeneficioSocialBeneficiarios
 16125                .AsNoTracking()
 16126                .Where(bh => idsAsigFamiliar.Contains(bh.BeneficioId) &&
 16127                             bh.Activo &&
 16128                             bh.VigenteDesde <= ultimoDiaPeriodo &&
 16129                             (bh.VigenteHasta == null || bh.VigenteHasta >= periodoDate))
 16130                .ToListAsync()
 16131            : [];
 132
 16133        var beneficiariosPorBeneficio = beneficiariosAsigFam
 0134            .GroupBy(bh => bh.BeneficioId)
 16135            .ToDictionary(g => g.Key, g => (IReadOnlyList<BeneficioSocialBeneficiario>)g.ToList());
 136
 16137        var compensaciones = await _context.ItemsLoteCompensacion
 16138            .AsNoTracking()
 16139            .Include(i => i.LoteCompensacion)
 16140                .ThenInclude(l => l.TipoCompensacion)
 16141                .ThenInclude(t => t.Configuraciones)
 16142                    .ThenInclude(c => c.CatalogoItem)
 16143            .Where(i => i.LoteCompensacion.Estado == "aprobado"
 16144                        && i.LoteCompensacion.PeriodoId == periodoId)
 16145            .ToListAsync();
 146
 16147        var novedadesConfirmadas = await _context.NovedadesPeriodo
 16148            .AsNoTracking()
 16149            .Where(n => n.PeriodoId == periodoId && n.Estado == "confirmada")
 16150            .ToListAsync();
 151
 16152        var remuneracionesPorGrado = remuneraciones
 37153            .GroupBy(r => r.GradoId)
 16154            .ToDictionary(
 17155                g => g.Key,
 33156                g => (IReadOnlyDictionary<int, RemuneracionGrado>)g
 37157                    .GroupBy(r => r.Item.Codigo)
 33158                    .ToDictionary(
 37159                        gg => gg.Key,
 107160                        gg => gg.OrderByDescending(r => r.VigenteDesde).First()));
 161
 16162        var tarifasPorCategoria = tarifasCategoria
 0163            .GroupBy(t => t.Categoria)
 16164            .ToDictionary(
 0165                g => g.Key,
 16166                g => (IReadOnlyDictionary<int, TarifaPorCategoria>)g
 0167                    .GroupBy(t => t.Item.Codigo)
 16168                    .ToDictionary(
 0169                        gg => gg.Key,
 16170                        gg => gg.OrderByDescending(t => t.VigenteDesde).First()));
 171
 16172        var compPersonal048018PorPersona = compPersonal048018
 1173            .GroupBy(c => c.PersonaId)
 19174            .ToDictionary(g => g.Key, g => g.OrderByDescending(c => c.VigenteDesde).First());
 175
 16176        var permanenciasPorEscalafon = permanencias
 1177            .GroupBy(t => t.EscalafonId)
 19178            .ToDictionary(g => g.Key, g => (IReadOnlyList<TablaPermanencia>)g.OrderBy(t => t.MesesHasta).ToList());
 179
 16180        var beneficiosPorPersona = beneficios
 1181            .GroupBy(b => b.PersonaId)
 18182            .ToDictionary(g => g.Key, g => (IReadOnlyList<BeneficioSocial>)g.ToList());
 183
 16184        var compensacionesPorPersona = compensaciones
 3185            .GroupBy(i => i.PersonaId)
 22186            .ToDictionary(g => g.Key, g => (IReadOnlyList<ItemLoteCompensacion>)g.ToList());
 187
 16188        var novedadesPorPersona = novedadesConfirmadas
 4189            .GroupBy(n => n.PersonaId)
 24190            .ToDictionary(g => g.Key, g => (IReadOnlyList<NovedadPeriodo>)g.ToList());
 191
 192        // Instructivo Asignación Familiar: fila más reciente por tipo_franja
 16193        var instructivoAsigFamiliarRaw = await _context.InstructivosAsigFamiliar
 16194            .AsNoTracking()
 16195            .Where(i => i.VigenteDesde <= periodoDate)
 16196            .ToListAsync();
 197
 16198        var instructivoAsigFamiliar = instructivoAsigFamiliarRaw
 0199            .GroupBy(i => i.TipoFranja)
 16200            .ToDictionary(
 0201                g => g.Key,
 16202                g => g.OrderByDescending(i => i.VigenteDesde).First());
 203
 204        // Instructivo PSF: fila más reciente por numero_categoria
 16205        var instructivoPsfRaw = await _context.InstructivosPsf
 16206            .AsNoTracking()
 16207            .Where(i => i.VigenteDesde <= periodoDate)
 16208            .ToListAsync();
 209
 16210        var instructivoPsf = instructivoPsfRaw
 0211            .GroupBy(i => (int)i.NumeroCategoria)
 16212            .ToDictionary(
 0213                g => g.Key,
 16214                g => g.OrderByDescending(i => i.VigenteDesde).First());
 215
 216        // Tabla Hogar: tramos vigentes, ordenados ASC con NULL al final
 16217        var tablaPorHogarRaw = await _context.TablasHogarConstituido
 16218            .AsNoTracking()
 16219            .Where(t => t.VigenteDesde <= periodoDate)
 16220            .ToListAsync();
 221
 16222        var tablaPorHogar = tablaPorHogarRaw
 0223            .GroupBy(t => t.HastaHaberes)
 0224            .Select(g => g.OrderByDescending(t => t.VigenteDesde).First())
 0225            .OrderBy(t => t.HastaHaberes.HasValue ? 0 : 1)
 0226            .ThenBy(t => t.HastaHaberes ?? decimal.MaxValue)
 16227            .ToList();
 228
 16229        var aguinaldos = await _context.Set<Aguinaldo>()
 16230            .AsNoTracking()
 16231            .Where(a => a.Anio == periodo.Anio)
 16232            .ToListAsync();
 233
 16234        var aguinaldosPorPersona = aguinaldos
 0235            .GroupBy(a => a.PersonaId)
 16236            .ToDictionary(g => g.Key, g => (IReadOnlyList<Aguinaldo>)g.ToList());
 237
 16238        var ordenPorGrado = await _context.Grados
 16239            .AsNoTracking()
 16240            .Where(g => g.Vigente)
 48241            .ToDictionaryAsync(g => g.Id, g => g.Orden);
 242
 16243        var diferenciaAscenso = await _context.CompensacionesDiferenciaAscenso
 16244            .AsNoTracking()
 16245            .Where(c => c.PeriodoId == periodoId && c.Estado == "pendiente")
 17246            .ToDictionaryAsync(c => c.PersonaId);
 247
 16248        var descuentosPersonales = await _context.DescuentosPersonalesPeriodo
 16249            .AsNoTracking()
 16250            .Where(d => d.PeriodoId == periodoId && d.Estado == "aprobado")
 16251            .ToListAsync();
 252
 16253        var descuentosPersonalesPorPersona = descuentosPersonales
 0254            .GroupBy(d => d.PersonaId)
 16255            .ToDictionary(g => g.Key, g => (IReadOnlyList<DescuentoPersonalPeriodo>)g.ToList());
 256
 16257        var fictos = await _context.FictosPersona
 16258            .AsNoTracking()
 16259            .Include(f => f.CatalogoItem)
 16260            .Include(f => f.Acreedor)
 16261            .Where(f => f.Activo)
 16262            .ToListAsync();
 263
 16264        var fictosPorPersona = fictos
 1265            .GroupBy(f => f.PersonaId)
 18266            .ToDictionary(g => g.Key, g => (IReadOnlyList<FictoPersona>)g.ToList());
 267
 16268        return new InsumosPeriodo
 16269        {
 16270            PeriodoId = periodoId,
 16271            ParametroPeriodo = parametros,
 16272            CatalogoItems = catalogoItems,
 16273            RemuneracionesPorGrado = remuneracionesPorGrado,
 16274            TarifasPorCategoria = tarifasPorCategoria,
 16275            CompPersonal048018PorPersona = compPersonal048018PorPersona,
 16276            PermanenciasPorEscalafon = permanenciasPorEscalafon,
 16277            FranjasIrpf = franjasIrpf,
 16278            TramosSanidad = tramosSanidad,
 16279            BeneficiosPorPersona = beneficiosPorPersona,
 16280            CompensacionesPorPersona = compensacionesPorPersona,
 16281            NovedadesPorPersona = novedadesPorPersona,
 16282            BeneficiariosPorBeneficio = beneficiariosPorBeneficio,
 16283            InstructivoAsigFamiliar = instructivoAsigFamiliar,
 16284            InstructivoPsf = instructivoPsf,
 16285            TablaPorHogar = tablaPorHogar,
 16286            AguinaldosPorPersona = aguinaldosPorPersona,
 16287            OrdenPorGrado = ordenPorGrado,
 16288            CompensacionesDiferenciaAscensoPorPersona = diferenciaAscenso,
 16289            DescuentosPersonalesPorPersona = descuentosPersonalesPorPersona,
 16290            FictosPorPersona = fictosPorPersona
 16291        };
 16292    }
 293}