< Summary

Information
Class: FAU.Logica.DTOs.InsumosPeriodo
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/DTOs/InsumosPeriodo.cs
Line coverage
88%
Covered lines: 68
Uncovered lines: 9
Coverable lines: 77
Total lines: 204
Line coverage: 88.3%
Branch coverage
69%
Covered branches: 32
Total branches: 46
Branch coverage: 69.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/DTOs/InsumosPeriodo.cs

#LineLine coverage
 1using FAU.Entidades;
 2
 3namespace FAU.Logica.DTOs;
 4
 5public sealed class InsumosPeriodo
 6{
 1037    public long PeriodoId { get; init; }
 10918    public ParametroPeriodo ParametroPeriodo { get; init; } = null!;
 29229    public IReadOnlyDictionary<long, IReadOnlyDictionary<int, RemuneracionGrado>> RemuneracionesPorGrado { get; init; } 
 10    // Filas de remuneraciones_grado con grupo_remuneracion no nulo (ej. "COMANDO", "SSGG").
 11    // Solo algunos OG (042.536, 048.015 confirmados) tienen tarifa distinta por cuerpo/escalafón;
 12    // el resto sigue resolviendo únicamente por RemuneracionesPorGrado (ver ObtenerRemuneracion).
 16613    public IReadOnlyDictionary<(long GradoId, int Codigo, string Grupo), RemuneracionGrado> RemuneracionesPorGradoYGrupo
 13814        new Dictionary<(long, int, string), RemuneracionGrado>();
 15    // escalafonId → grupo de remuneración ("COMANDO"/"SSGG"/null). Mapeo hardcodeado en
 16    // InsumosPeriodoLoader (AV→COMANDO, SG→SSGG); el resto de los escalafones no está mapeado.
 237617    public IReadOnlyDictionary<long, string?> GrupoPorEscalafon { get; init; } = new Dictionary<long, string?>();
 31918    public IReadOnlyDictionary<long, IReadOnlyList<TablaPermanencia>> PermanenciasPorEscalafon { get; init; } = new Dict
 24919    public IReadOnlyList<FranjaIrpf> FranjasIrpf { get; init; } = Array.Empty<FranjaIrpf>();
 20    // Tramos de Sanidad Militar (Art. 94 Ley 18.834), ordenados por Desde ASC
 21321    public IReadOnlyList<TramoSanidadMilitar> TramosSanidad { get; init; } = Array.Empty<TramoSanidadMilitar>();
 76922    public IReadOnlyList<CatalogoItem> CatalogoItems { get; init; } = Array.Empty<CatalogoItem>();
 19923    public IReadOnlyDictionary<long, IReadOnlyList<BeneficioSocial>> BeneficiosPorPersona { get; init; } = new Dictionar
 19824    public IReadOnlyDictionary<long, IReadOnlyList<ItemLoteCompensacion>> CompensacionesPorPersona { get; init; } = new 
 21625    public IReadOnlyDictionary<long, IReadOnlyList<NovedadPeriodo>> NovedadesPorPersona { get; init; } = new Dictionary<
 26    // beneficioId → hijos registrados (para ASIGNACION_FAMILIAR)
 19827    public IReadOnlyDictionary<long, IReadOnlyList<BeneficioSocialBeneficiario>> BeneficiariosPorBeneficio { get; init; 
 28
 29    // Instructivos DFC — tipoFranja → registro vigente
 19830    public IReadOnlyDictionary<string, InstructivoAsigFamiliar> InstructivoAsigFamiliar { get; init; } = new Dictionary<
 31    // Instructivos DFC — numCategoria → registro vigente
 19832    public IReadOnlyDictionary<int, InstructivoPsf> InstructivoPsf { get; init; } = new Dictionary<int, InstructivoPsf>(
 33    // Tabla hogar constituido — tramos ordenados (hasta_haberes ASC, NULL al final)
 19834    public IReadOnlyList<TablaHogarConstituido> TablaPorHogar { get; init; } = Array.Empty<TablaHogarConstituido>();
 35
 36    // Aguinaldos (SAC) del año por persona — usado por AguinaldoCalculator (SIT14/15/18/20)
 16237    public IReadOnlyDictionary<long, IReadOnlyList<Aguinaldo>> AguinaldosPorPersona { get; init; } = new Dictionary<long
 38
 39    // Diferencias de haberes por ascenso (OG 042.615) — cargado desde compensaciones_diferencia_ascenso
 19740    public IReadOnlyDictionary<long, CompensacionDiferenciaAscenso> CompensacionesDiferenciaAscensoPorPersona { get; ini
 41
 42    // Orden de cada grado (para determinar porcentaje DI: clases 35% vs alistados 30%)
 43    // Cargado desde la tabla grados; key = grado_id, value = grado.orden
 38644    public IReadOnlyDictionary<long, short> OrdenPorGrado { get; init; } = new Dictionary<long, short>();
 45
 46    // Descuentos personales aprobados por persona (COFAnS, retenciones y otros).
 15447    public IReadOnlyDictionary<long, IReadOnlyList<DescuentoPersonalPeriodo>> DescuentosPersonalesPorPersona { get; init
 48
 7849    public IReadOnlyDictionary<long, IReadOnlyList<FictoPersona>> FictosPorPersona { get; init; } =
 13850        new Dictionary<long, IReadOnlyList<FictoPersona>>();
 51
 52    // Tarifas por categoría (no por grado) — ej. Prima Técnica A/B/C, ASID_VUELO, SAR.
 53    // key externa = categoría (p.ej. "A"), key interna = código de catalogo_items.
 10354    public IReadOnlyDictionary<string, IReadOnlyDictionary<int, TarifaPorCategoria>> TarifasPorCategoria { get; init; } 
 13855        new Dictionary<string, IReadOnlyDictionary<int, TarifaPorCategoria>>();
 56
 57    // 048.018 — Compensación Personal: importe individual por persona, vigente al período.
 19158    public IReadOnlyDictionary<long, CompPersonal048018> CompPersonal048018PorPersona { get; init; } =
 13859        new Dictionary<long, CompPersonal048018>();
 60
 61    /// <summary>
 62    /// Resuelve la remuneración de un OG para un grado. Si se pasa <paramref name="grupo"/> y
 63    /// existe una fila específica para ese (grado, OG, grupo), se usa esa; si no, cae al valor
 64    /// general de <see cref="RemuneracionesPorGrado"/> (comportamiento previo, sin cambios).
 65    /// </summary>
 66    public RemuneracionGrado? ObtenerRemuneracion(long gradoId, int codigoItem, string? grupo = null)
 67    {
 269168        if (grupo is not null &&
 269169            RemuneracionesPorGradoYGrupo.TryGetValue((gradoId, codigoItem, grupo), out var especifico))
 70        {
 571            return especifico;
 72        }
 73
 268674        if (RemuneracionesPorGrado.TryGetValue(gradoId, out var items) && items.TryGetValue(codigoItem, out var remunera
 75        {
 24776            return remuneracion;
 77        }
 78
 243979        return null;
 80    }
 81
 82    public TarifaPorCategoria? ObtenerTarifaCategoria(string categoria, int codigoItem)
 83    {
 684        if (TarifasPorCategoria.TryGetValue(categoria, out var items) && items.TryGetValue(codigoItem, out var tarifa))
 85        {
 586            return tarifa;
 87        }
 88
 189        return null;
 90    }
 91
 92    public CompPersonal048018? ObtenerCompPersonal048018(long personaId)
 93    {
 9494        return CompPersonal048018PorPersona.TryGetValue(personaId, out var comp) ? comp : null;
 95    }
 96
 97    /// <summary>
 98    /// Retorna la tasa mínima registrada para un ítem entre todos los grados.
 99    /// Usado para obtener la tasa de subalterno del progresivo (044.001 = $114.01/año)
 100    /// cuando hay que calcular el tramo de tropa previo al ascenso a oficial.
 101    /// La tasa mínima corresponde siempre a los grados de tropa/subalterno.
 102    /// </summary>
 103    public decimal ObtenerTasaMinimaProgresivo(int codigoItem)
 104    {
 0105        var minRate = 0m;
 0106        foreach (var gradoItems in RemuneracionesPorGrado.Values)
 107        {
 0108            if (gradoItems.TryGetValue(codigoItem, out var rem) && rem.Monto > 0)
 109            {
 0110                if (minRate == 0m || rem.Monto < minRate)
 0111                    minRate = rem.Monto;
 112            }
 113        }
 0114        return minRate;
 115    }
 116
 117    public TablaPermanencia? ObtenerPermanencia(long escalafonId, long gradoId, int mesesServicio, bool riesgoVuelo)
 118    {
 84119        if (PermanenciasPorEscalafon.TryGetValue(escalafonId, out var filas))
 120        {
 121            // Lógica legacy (SUM33106.PRG / CALC_HAB.PRG):
 122            // Recorre los tramos mientras tiempo_pm (MesesHasta) <= meses del funcionario
 123            // y conserva el último que cumplió la condición (monto creciente por antigüedad).
 12124            return filas
 12125                .Where(p => p.GradoId == gradoId)
 12126                .Where(p => p.AplicaRiesgoVuelo == riesgoVuelo)
 12127                .Where(p => p.MesesHasta <= mesesServicio)
 12128                .OrderByDescending(p => p.MesesHasta)
 12129                .FirstOrDefault();
 130        }
 131
 72132        return null;
 133    }
 134
 135    /// <summary>
 136    /// Retorna el tramo de Sanidad Militar cuyo rango [Desde, Hasta] contiene la base imponible.
 137    /// Hasta == null representa el último tramo (sin tope superior).
 138    /// </summary>
 139    public TramoSanidadMilitar? ObtenerTramoSanidad(decimal baseImponible)
 140    {
 51141        return TramosSanidad.FirstOrDefault(t =>
 65142            baseImponible >= t.Desde && (t.Hasta is null || baseImponible <= t.Hasta));
 143    }
 144
 145    public IReadOnlyList<BeneficioSocial> ObtenerBeneficios(long personaId)
 146    {
 45147        return BeneficiosPorPersona.TryGetValue(personaId, out var beneficios)
 45148            ? beneficios
 45149            : Array.Empty<BeneficioSocial>();
 150    }
 151
 152    public IReadOnlyList<ItemLoteCompensacion> ObtenerCompensaciones(long personaId)
 153    {
 44154        return CompensacionesPorPersona.TryGetValue(personaId, out var items)
 44155            ? items
 44156            : Array.Empty<ItemLoteCompensacion>();
 157    }
 158
 159    public NovedadPeriodo? ObtenerNovedad(long personaId)
 160    {
 1161        return NovedadesPorPersona.TryGetValue(personaId, out var novedades)
 1162            ? novedades.FirstOrDefault()
 1163            : null;
 164    }
 165
 166    /// <summary>
 167    /// Retorna la novedad de tipo 'dias_eximidos' para el prorrateo salarial.
 168    /// 'subsidio_enfermedad' no reduce el sueldo base — tiene su propio cálculo (pendiente).
 169    /// </summary>
 170    public NovedadPeriodo? ObtenerNovedadEximidos(long personaId)
 171    {
 18172        if (!NovedadesPorPersona.TryGetValue(personaId, out var novedades))
 15173            return null;
 6174        return novedades.FirstOrDefault(n => n.Tipo == "dias_eximidos");
 175    }
 176
 177    public IReadOnlyList<NovedadPeriodo> ObtenerNovedades(long personaId)
 178    {
 43179        return NovedadesPorPersona.TryGetValue(personaId, out var novedades)
 43180            ? novedades
 43181            : Array.Empty<NovedadPeriodo>();
 182    }
 183
 184    public CompensacionDiferenciaAscenso? ObtenerDiferenciaAscenso(long personaId)
 185    {
 43186        return CompensacionesDiferenciaAscensoPorPersona.TryGetValue(personaId, out var diff)
 43187            ? diff
 43188            : null;
 189    }
 190
 191    public IReadOnlyList<DescuentoPersonalPeriodo> ObtenerDescuentosPersonales(long personaId)
 192    {
 0193        return DescuentosPersonalesPorPersona.TryGetValue(personaId, out var descuentos)
 0194            ? descuentos
 0195            : Array.Empty<DescuentoPersonalPeriodo>();
 196    }
 197
 198    public IReadOnlyList<FictoPersona> ObtenerFictos(long personaId)
 199    {
 45200        return FictosPorPersona.TryGetValue(personaId, out var fictos)
 45201            ? fictos
 45202            : Array.Empty<FictoPersona>();
 203    }
 204}