< Summary

Information
Class: FAU.DataAccess.Repositories.ReciboRepository
Assembly: FAU.DataAccess
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.DataAccess/Repositories/ReciboRepository.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 172
Coverable lines: 172
Total lines: 233
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 86
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%
ObtenerVersionMaximaAsync()100%210%
ObtenerResumenesAsync()0%156120%
ObtenerDatosReciboAsync()0%4422660%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.DataAccess/Repositories/ReciboRepository.cs

#LineLine coverage
 1using FAU.Entidades;
 2using Microsoft.EntityFrameworkCore;
 3
 4namespace FAU.DataAccess.Repositories;
 5
 6public class ReciboRepository : IReciboRepository
 7{
 8    private readonly ApplicationDbContext _context;
 9
 010    public ReciboRepository(ApplicationDbContext context)
 11    {
 012        _context = context;
 013    }
 14
 15    public async Task<int> ObtenerVersionMaximaAsync(long periodoId)
 16    {
 017        return await _context.LiquidacionItems
 018            .AsNoTracking()
 019            .Where(i => i.PeriodoId == periodoId)
 020            .MaxAsync(i => (int?)i.Version) ?? 0;
 021    }
 22
 23    public async Task<List<ReciboResumenDto>> ObtenerResumenesAsync(long periodoId, int version, ReciboFiltroRequest fil
 24    {
 025        var query = _context.RelacionesLaborales
 026            .AsNoTracking()
 027            .Include(r => r.Persona)
 028                .ThenInclude(p => p.CuentasBancarias)
 029                    .ThenInclude(c => c.Banco)
 030            .Include(r => r.Regimen)
 031            .Include(r => r.Programa)
 032            .Include(r => r.Unidad)
 033            .Where(r => r.Estado == EstadoRelacion.Activo);
 34
 035        if (!string.IsNullOrWhiteSpace(filtro.Cedula))
 036            query = query.Where(r => r.Persona.Cedula == filtro.Cedula);
 37
 038        if (filtro.ProgramaId.HasValue)
 039            query = query.Where(r => r.ProgramaId == filtro.ProgramaId.Value);
 40
 041        if (filtro.UnidadId.HasValue)
 042            query = query.Where(r => r.UnidadId == filtro.UnidadId.Value);
 43
 044        var relaciones = await query.ToListAsync();
 45
 46        // Obtener cédulas que tienen liquidación en el período/versión
 047        var cedulasConLiquidacion = await _context.LiquidacionEstadosPersonal
 048            .AsNoTracking()
 049            .Where(e => e.PeriodoId == periodoId && e.Version == version)
 050            .Select(e => e.Cedula)
 051            .ToHashSetAsync();
 52
 53        // Calcular líquido pagable (suma de todos los ítems por cédula)
 054        var liquidosPorCedula = await _context.LiquidacionItems
 055            .AsNoTracking()
 056            .Where(i => i.PeriodoId == periodoId && i.Version == version)
 057            .GroupBy(i => i.Cedula)
 058            .Select(g => new { Cedula = g.Key, Liquido = g.Sum(i => i.Importe) })
 059            .ToDictionaryAsync(x => x.Cedula, x => x.Liquido);
 60
 061        var resultados = relaciones
 062            .Where(r => cedulasConLiquidacion.Contains(r.Persona.Cedula))
 063            .ToList();
 64
 065        if (!string.IsNullOrWhiteSpace(filtro.Regimen))
 66        {
 067            var regimenNorm = filtro.Regimen.Replace('_', '-').ToLowerInvariant();
 068            resultados = regimenNorm switch
 069            {
 070                "ley-vieja" => resultados.Where(r => r.Regimen.EsLeyVieja).ToList(),
 071                "ley-nueva" => resultados.Where(r => !r.Regimen.EsLeyVieja).ToList(),
 072                _ => resultados.Where(r => r.Regimen.NumeroLey.Contains(filtro.Regimen, StringComparison.OrdinalIgnoreCa
 073            };
 74        }
 75
 076        return resultados.Select(r => new ReciboResumenDto
 077        {
 078            RelacionLaboralId   = r.Id,
 079            Cedula       = r.Persona.Cedula,
 080            Nombre       = r.Persona.PrimerNombre,
 081            Apellido     = r.Persona.PrimerApellido,
 082            Regimen      = r.Regimen.NumeroLey,
 083            Programa     = r.Programa?.Denominacion ?? string.Empty,
 084            Unidad       = r.Unidad?.Denominacion ?? string.Empty,
 085            LiquidoPagable = liquidosPorCedula.TryGetValue(r.Persona.Cedula, out var liq) ? liq : 0m
 086        }).ToList();
 087    }
 88
 89    public async Task<ReciboDto?> ObtenerDatosReciboAsync(long periodoId, int version, long relacionId)
 90    {
 091        var relacion = await _context.RelacionesLaborales
 092            .AsNoTracking()
 093            .Include(r => r.Persona)
 094                .ThenInclude(p => p.CuentasBancarias.Where(c => c.Estado == "activa"))
 095                    .ThenInclude(c => c.Banco)
 096            .Include(r => r.Regimen)
 097            .Include(r => r.Programa)
 098            .Include(r => r.Unidad)
 099            .Include(r => r.SubUnidad)
 0100            .Include(r => r.Grado)
 0101            .Include(r => r.Escalafon)
 0102            .FirstOrDefaultAsync(r => r.Id == relacionId);
 103
 0104        if (relacion == null) return null;
 105
 0106        var cedula = relacion.Persona.Cedula;
 107
 0108        var items = await _context.LiquidacionItems
 0109            .AsNoTracking()
 0110            .Where(i => i.PeriodoId == periodoId && i.Version == version && i.Cedula == cedula)
 0111            .ToListAsync();
 112
 0113        if (!items.Any()) return null;
 114
 0115        var periodo = await _context.PeriodosLiquidacion
 0116            .AsNoTracking()
 0117            .Where(p => p.Id == periodoId)
 0118            .Select(p => new { p.Anio, p.Mes })
 0119            .FirstOrDefaultAsync();
 120
 0121        var situacionCodigo = await _context.Situaciones
 0122            .AsNoTracking()
 0123            .Where(s => s.Id == relacion.SituacionId)
 0124            .Select(s => s.Codigo)
 0125            .FirstOrDefaultAsync() ?? string.Empty;
 126
 127        // Obtener tipos de catálogo para clasificar ítems
 0128        var codigosNumericos = items
 0129            .Select(i => i.CodigoConcepto)
 0130            .Where(c => int.TryParse(c, out _))
 0131            .Select(int.Parse)
 0132            .ToHashSet();
 133
 0134        var catalogoPorCodigo = await _context.CatalogoItems
 0135            .AsNoTracking()
 0136            .Where(c => codigosNumericos.Contains(c.Codigo))
 0137            .ToDictionaryAsync(c => c.Codigo.ToString(), c => c.Tipo);
 138
 0139        var haberes              = new List<ReciboItemDto>();
 0140        var beneficios           = new List<ReciboItemDto>();
 0141        var descuentosLegales    = new List<ReciboItemDto>();
 0142        var descuentosPersonales = new List<ReciboItemDto>();
 143
 0144        foreach (var item in items.OrderBy(i => i.CodigoConcepto))
 145        {
 0146            var dto = new ReciboItemDto
 0147            {
 0148                Codigo        = item.CodigoConcepto,
 0149                Descripcion   = item.NombreConcepto,
 0150                RubroContable = item.RubroContable,
 0151                Monto         = item.Importe
 0152            };
 153
 0154            if (item.Importe > 0)
 155            {
 0156                var tipo = catalogoPorCodigo.TryGetValue(item.CodigoConcepto, out var t) ? t : "haber_normal";
 0157                if (tipo.StartsWith("beneficio_social", StringComparison.OrdinalIgnoreCase))
 0158                    beneficios.Add(dto);
 159                else
 0160                    haberes.Add(dto);
 161            }
 0162            else if (catalogoPorCodigo.TryGetValue(item.CodigoConcepto, out var tipo2) &&
 0163                     string.Equals(tipo2, "descuento_legal", StringComparison.OrdinalIgnoreCase))
 164            {
 0165                descuentosLegales.Add(dto);
 166            }
 167            else
 168            {
 0169                descuentosPersonales.Add(dto);
 170            }
 171        }
 172
 0173        var totalHaberes              = haberes.Sum(i => i.Monto);
 0174        var totalBeneficios           = beneficios.Sum(i => i.Monto);
 0175        var totalDescuentosLegales    = Math.Abs(descuentosLegales.Sum(i => i.Monto));
 0176        var totalDescuentosPersonales = Math.Abs(descuentosPersonales.Sum(i => i.Monto));
 0177        var totalDescuentos           = totalDescuentosLegales + totalDescuentosPersonales;
 178
 0179        var nominal     = totalHaberes + totalBeneficios;
 0180        var exactLiquid = nominal - totalDescuentosLegales - totalDescuentosPersonales;
 0181        var aCobrar     = Math.Round(exactLiquid, 0, MidpointRounding.AwayFromZero);
 0182        var ajuste      = aCobrar - exactLiquid;
 183
 184        // Civil: SIT19 (presupuestado), SIT20 (baja civil), SIT21 (contratado)
 0185        var esCivil = situacionCodigo is "SIT19" or "SIT20" or "SIT21";
 186
 0187        var cuentaActiva = relacion.Persona.CuentasBancarias.FirstOrDefault();
 188
 0189        return new ReciboDto
 0190        {
 0191            Anio            = periodo?.Anio ?? 0,
 0192            Mes             = periodo?.Mes ?? 0,
 0193            RelacionLaboralId      = relacion.Id,
 0194            Cedula          = cedula,
 0195            PrimerNombre    = relacion.Persona.PrimerNombre,
 0196            SegundoNombre   = relacion.Persona.SegundoNombre ?? string.Empty,
 0197            PrimerApellido  = relacion.Persona.PrimerApellido,
 0198            SegundoApellido = relacion.Persona.SegundoApellido ?? string.Empty,
 0199            Grado           = relacion.Grado?.Denominacion ?? string.Empty,
 0200            Escalafon       = relacion.Escalafon?.Denominacion ?? string.Empty,
 0201            Regimen         = relacion.Regimen.NumeroLey,
 0202            Unidad          = relacion.Unidad?.Denominacion ?? string.Empty,
 0203            Programa        = relacion.Programa?.Denominacion ?? string.Empty,
 0204            UnidadCodigo    = relacion.Unidad?.Codigo ?? string.Empty,
 0205            Compania        = relacion.SubUnidad?.Codigo ?? string.Empty,
 0206            EsOficial       = relacion.Grado?.EsOficial ?? false,
 0207            EsSubalterno    = relacion.Grado?.EsSubalterno ?? false,
 0208            EsCivil         = esCivil,
 0209            FechaInicio     = relacion.FechaInicio,
 0210            FechaUltimoAscenso = relacion.FechaUltimoAscenso,
 0211            Haberes               = haberes,
 0212            Beneficios            = beneficios,
 0213            DescuentosLegales     = descuentosLegales,
 0214            DescuentosPersonales  = descuentosPersonales,
 0215            TotalHaberes          = totalHaberes,
 0216            TotalBeneficios       = totalBeneficios,
 0217            TotalDescuentosLegales    = totalDescuentosLegales,
 0218            TotalDescuentosPersonales = totalDescuentosPersonales,
 0219            TotalDescuentos       = totalDescuentos,
 0220            Nominal               = nominal,
 0221            LiquidoPagable        = aCobrar,
 0222            ACobrar               = aCobrar,
 0223            Ajuste                = ajuste,
 0224            DatosBancarios = cuentaActiva != null
 0225                ? new ReciboDatosBancariosDto
 0226                  {
 0227                      Banco  = cuentaActiva.Banco?.Nombre,
 0228                      Cuenta = cuentaActiva.NumeroCuenta
 0229                  }
 0230                : new ReciboDatosBancariosDto { Observacion = "Sin cuenta registrada" }
 0231        };
 0232    }
 233}