< Summary

Information
Class: FAU.Logica.Services.ReportePresupuestalService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/ReportePresupuestalService.cs
Line coverage
92%
Covered lines: 193
Uncovered lines: 15
Coverable lines: 208
Total lines: 331
Line coverage: 92.7%
Branch coverage
84%
Covered branches: 22
Total branches: 26
Branch coverage: 84.6%
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/Services/ReportePresupuestalService.cs

#LineLine coverage
 1using System.Globalization;
 2using System.Text;
 3using FAU.DataAccess.Repositories;
 4using FAU.Entidades;
 5
 6namespace FAU.Logica.Services;
 7
 8public class ReportePresupuestalService : IReportePresupuestalService
 9{
 10    private readonly IReportePresupuestalRepository _repo;
 11    private readonly IArchivoOrganismoService _siifService;
 12
 1413    public ReportePresupuestalService(
 1414        IReportePresupuestalRepository repo,
 1415        IArchivoOrganismoService siifService)
 16    {
 1417        _repo = repo;
 1418        _siifService = siifService;
 1419    }
 20
 21    // ─── Resumen por programa ────────────────────────────────────────────────
 22
 23    public async Task<ResumenProgramaDto> ObtenerResumenProgramaAsync(long periodoId)
 24    {
 225        var version = await _repo.ObtenerVersionMaximaAsync(periodoId);
 226        var items = await _repo.ObtenerItemsConDatosAsync(periodoId, version);
 27
 228        var grupos = items
 729            .GroupBy(i => (i.ProgramaId, i.Programa, i.RegimenId, i.Regimen));
 30
 231        var filas = new List<ResumenProgramaFilaDto>();
 32
 1033        foreach (var g in grupos)
 34        {
 1135            var haberes = g.Where(i => i.Importe > 0).Sum(i => i.Importe);
 1036            var descuentos = g.Where(i => i.Importe < 0).Sum(i => i.Importe);
 37
 338            filas.Add(new ResumenProgramaFilaDto
 339            {
 340                ProgramaId       = g.Key.ProgramaId,
 341                Programa         = g.Key.Programa,
 342                RegimenId        = g.Key.RegimenId,
 343                Regimen          = g.Key.Regimen,
 344                TotalNominal     = haberes,
 345                TotalRetenciones = Math.Abs(descuentos),
 346                Liquido          = haberes + descuentos
 347            });
 48        }
 49
 250        var totales = new ResumenProgramaFilaDto
 251        {
 252            Programa         = "TOTAL",
 253            Regimen          = string.Empty,
 354            TotalNominal     = filas.Sum(f => f.TotalNominal),
 355            TotalRetenciones = filas.Sum(f => f.TotalRetenciones),
 356            Liquido          = filas.Sum(f => f.Liquido)
 257        };
 58
 259        return new ResumenProgramaDto { Filas = filas, Totales = totales };
 260    }
 61
 62    public async Task<byte[]> GenerarCsvResumenProgramaAsync(long periodoId)
 63    {
 164        var resumen = await ObtenerResumenProgramaAsync(periodoId);
 165        var sb = new StringBuilder();
 166        sb.AppendLine("Programa;Régimen;Total Nominal;Total Retenciones;Líquido");
 67
 468        foreach (var f in resumen.Filas)
 169            sb.AppendLine($"{f.Programa};{f.Regimen};{F(f.TotalNominal)};{F(f.TotalRetenciones)};{F(f.Liquido)}");
 70
 171        var t = resumen.Totales;
 172        sb.AppendLine($"{t.Programa};{t.Regimen};{F(t.TotalNominal)};{F(t.TotalRetenciones)};{F(t.Liquido)}");
 73
 174        return Encoding.UTF8.GetBytes(sb.ToString());
 175    }
 76
 77    // ─── Rubro 083 (delega a ArchivoOrganismoService) ───────────────────────
 78
 79    public Task<SiifResumenDto> ObtenerResumenRubro083Async(long periodoId)
 180        => _siifService.ObtenerResumenSiifAsync(periodoId);
 81
 82    public async Task<byte[]> GenerarCsvRubro083Async(long periodoId)
 83    {
 084        var resumen = await _siifService.ObtenerResumenSiifAsync(periodoId);
 085        var sb = new StringBuilder();
 086        sb.AppendLine(
 087            "Programa;Régimen;" +
 088            "HabNorGrab(Con083);HabsAnGrab(Con083);HabsNoGrab(Con083);BenSocGrab(Con083);BenSocNoGr(Con083);DtoLegGrab(C
 089            "HabNorGrab(Sin083);HabsAnGrab(Sin083);HabsNoGrab(Sin083);BenSocGrab(Sin083);BenSocNoGr(Sin083);DtoLegGrab(S
 90
 091        foreach (var f in resumen.Filas)
 92        {
 093            var c = f.ConRubro083;
 094            var s = f.SinRubro083;
 095            sb.AppendLine(
 096                $"{f.Programa};{f.Regimen};" +
 097                $"{F(c.HabNorGrab)};{F(c.HabsAnGrab)};{F(c.HabsNoGrab)};{F(c.BenSocGrab)};{F(c.BenSocNoGr)};{F(c.DtoLegG
 098                $"{F(s.HabNorGrab)};{F(s.HabsAnGrab)};{F(s.HabsNoGrab)};{F(s.BenSocGrab)};{F(s.BenSocNoGr)};{F(s.DtoLegG
 99        }
 100
 0101        return Encoding.UTF8.GetBytes(sb.ToString());
 0102    }
 103
 104    // ─── Padrón por rubro ────────────────────────────────────────────────────
 105
 106    public async Task<PadronRubroDto> ObtenerPadronRubroAsync(long periodoId)
 107    {
 2108        var version = await _repo.ObtenerVersionMaximaAsync(periodoId);
 2109        var items = await _repo.ObtenerItemsConDatosAsync(periodoId, version);
 110
 11111        var rubros = items.Select(i => i.RubroContable).Distinct().OrderBy(r => r).ToList();
 112
 2113        var filas = items
 5114            .GroupBy(i => i.Cedula)
 2115            .Select(g =>
 2116            {
 3117                var primero = g.First();
 3118                return new PadronRubroFilaDto
 3119                {
 3120                    Cedula    = primero.Cedula,
 3121                    Nombre    = primero.Nombre,
 3122                    Grado     = primero.Grado,
 3123                    Escalafon = primero.Escalafon,
 3124                    Regimen   = primero.Regimen,
 3125                    Programa  = primero.Programa,
 3126                    Unidad    = primero.Unidad,
 3127                    MontosPorRubro = g
 5128                        .GroupBy(i => i.RubroContable)
 15129                        .ToDictionary(gr => gr.Key, gr => gr.Sum(i => i.Importe))
 3130                };
 2131            })
 2132            .ToList();
 133
 2134        return new PadronRubroDto { Rubros = rubros, Filas = filas };
 2135    }
 136
 137    public async Task<byte[]> GenerarCsvPadronRubroAsync(long periodoId)
 138    {
 1139        var padron = await ObtenerPadronRubroAsync(periodoId);
 1140        var sb = new StringBuilder();
 141
 1142        sb.AppendLine(
 1143            "Cédula;Nombre;Grado;Escalafón;Régimen;Programa;Unidad;" +
 1144            string.Join(";", padron.Rubros));
 145
 4146        foreach (var f in padron.Filas)
 147        {
 1148            var montos = string.Join(";",
 1149                padron.Rubros.Select(r =>
 3150                    f.MontosPorRubro.TryGetValue(r, out var m) ? F(m) : "0.00"));
 151
 1152            sb.AppendLine($"{f.Cedula};{f.Nombre};{f.Grado};{f.Escalafon};{f.Regimen};{f.Programa};{f.Unidad};{montos}")
 153        }
 154
 1155        return Encoding.UTF8.GetBytes(sb.ToString());
 1156    }
 157
 158    // ─── Padrón mensual ──────────────────────────────────────────────────────
 159
 160    public async Task<List<PadronMensualFilaDto>> ObtenerPadronMensualAsync(long periodoId)
 161    {
 2162        var version = await _repo.ObtenerVersionMaximaAsync(periodoId);
 2163        var items = await _repo.ObtenerItemsConDatosAsync(periodoId, version);
 164
 2165        return items
 5166            .GroupBy(i => i.Cedula)
 2167            .Select(g =>
 2168            {
 3169                var primero = g.First();
 11170                var haberes = g.Where(i => i.Importe > 0).Sum(i => i.Importe);
 10171                var descuentos = g.Where(i => i.Importe < 0).Sum(i => i.Importe);
 2172
 3173                return new PadronMensualFilaDto
 3174                {
 3175                    Cedula           = primero.Cedula,
 3176                    Nombre           = primero.Nombre,
 3177                    Grado            = primero.Grado,
 3178                    Escalafon        = primero.Escalafon,
 3179                    Regimen          = primero.Regimen,
 3180                    Programa         = primero.Programa,
 3181                    Unidad           = primero.Unidad,
 3182                    TotalHaberes     = haberes,
 3183                    TotalDescuentos  = Math.Abs(descuentos),
 3184                    Liquido          = haberes + descuentos
 3185                };
 2186            })
 2187            .ToList();
 2188    }
 189
 190    public async Task<byte[]> GenerarCsvPadronMensualAsync(long periodoId)
 191    {
 1192        var filas = await ObtenerPadronMensualAsync(periodoId);
 1193        var sb = new StringBuilder();
 1194        sb.AppendLine("Cédula;Nombre;Grado;Escalafón;Régimen;Programa;Unidad;Total Haberes;Total Descuentos;Líquido");
 195
 4196        foreach (var f in filas)
 1197            sb.AppendLine($"{f.Cedula};{f.Nombre};{f.Grado};{f.Escalafon};{f.Regimen};{f.Programa};{f.Unidad};{F(f.Total
 198
 1199        return Encoding.UTF8.GetBytes(sb.ToString());
 1200    }
 201
 202    // ─── Movimientos de personal ─────────────────────────────────────────────
 203
 204    public async Task<List<MovimientoPersonalDto>> ObtenerMovimientosAsync(long periodoId)
 205    {
 2206        var movimientos = await _repo.ObtenerMovimientosAsync(periodoId);
 207
 5208        return movimientos.Select(m => new MovimientoPersonalDto
 5209        {
 5210            Cedula          = m.Cedula,
 5211            Nombre          = m.Nombre,
 5212            TipoMovimiento  = m.TipoMovimiento,
 5213            FechaMovimiento = m.FechaMovimiento,
 5214            Motivo          = m.Observaciones,
 5215            RegimenAnterior = null,
 5216            RegimenNuevo    = null
 5217        }).ToList();
 2218    }
 219
 220    public async Task<byte[]> GenerarCsvMovimientosAsync(long periodoId)
 221    {
 1222        var filas = await ObtenerMovimientosAsync(periodoId);
 1223        var sb = new StringBuilder();
 1224        sb.AppendLine("Cédula;Nombre;Tipo Movimiento;Fecha;Motivo");
 225
 4226        foreach (var f in filas)
 1227            sb.AppendLine(
 1228                $"{f.Cedula};{f.Nombre};{f.TipoMovimiento};" +
 1229                $"{f.FechaMovimiento:dd/MM/yyyy};{f.Motivo ?? string.Empty}");
 230
 1231        return Encoding.UTF8.GetBytes(sb.ToString());
 1232    }
 233
 234    // ─── Padrón diferencias ──────────────────────────────────────────────────
 235
 236    public async Task<PadronDiferenciasDto> ObtenerDiferenciasAsync(long periodoId)
 237    {
 3238        var version = await _repo.ObtenerVersionMaximaAsync(periodoId);
 3239        var items = await _repo.ObtenerItemsConDatosAsync(periodoId, version);
 240
 3241        var resumenAnterior = await _repo.ObtenerResumenPeriodoAnteriorAsync(periodoId);
 242
 243        // Resumen por cédula del período actual
 3244        var resumenActual = items
 5245            .GroupBy(i => i.Cedula)
 3246            .Select(g =>
 3247            {
 5248                var primero = g.First();
 10249                var liq = g.Sum(i => i.Importe);
 5250                return new DiferenciaFilaDto
 5251                {
 5252                    Cedula   = primero.Cedula,
 5253                    Nombre   = primero.Nombre,
 5254                    Grado    = primero.Grado,
 5255                    Regimen  = primero.Regimen,
 5256                    Programa = primero.Programa,
 5257                    Liquido  = liq
 5258                };
 3259            })
 3260            .ToList();
 261
 8262        var cedulasActual = resumenActual.Select(f => f.Cedula).ToHashSet();
 263
 264        List<DiferenciaFilaDto> altas;
 3265        List<DiferenciaFilaDto> bajas = new();
 266
 3267        if (resumenAnterior is null)
 268        {
 269            // Sin período anterior: todas son altas
 1270            altas = resumenActual;
 271        }
 272        else
 273        {
 5274            altas = resumenActual.Where(f => !resumenAnterior.ContainsKey(f.Cedula)).ToList();
 5275            bajas = resumenAnterior.Values.Where(f => !cedulasActual.Contains(f.Cedula)).ToList();
 276        }
 277
 3278        return new PadronDiferenciasDto { Altas = altas, Bajas = bajas };
 3279    }
 280
 281    public async Task<byte[]> GenerarCsvDiferenciasAsync(long periodoId)
 282    {
 1283        var resultado = await ObtenerDiferenciasAsync(periodoId);
 1284        var sb = new StringBuilder();
 1285        sb.AppendLine("Tipo;Cédula;Nombre;Grado;Régimen;Programa;Líquido");
 286
 4287        foreach (var f in resultado.Altas)
 1288            sb.AppendLine($"ALTA;{f.Cedula};{f.Nombre};{f.Grado};{f.Regimen};{f.Programa};{F(f.Liquido)}");
 289
 4290        foreach (var f in resultado.Bajas)
 1291            sb.AppendLine($"BAJA;{f.Cedula};{f.Nombre};{f.Grado};{f.Regimen};{f.Programa};{F(f.Liquido)}");
 292
 1293        return Encoding.UTF8.GetBytes(sb.ToString());
 1294    }
 295
 296    // ─── No disponibles ──────────────────────────────────────────────────────
 297
 298    public async Task<List<NoDisponibleDto>> ObtenerNoDisponiblesAsync(long periodoId)
 299    {
 2300        var version = await _repo.ObtenerVersionMaximaAsync(periodoId);
 2301        var datos = await _repo.ObtenerNoDisponiblesAsync(periodoId, version);
 302
 6303        return datos.Select(d => new NoDisponibleDto
 6304        {
 6305            Cedula               = d.Cedula,
 6306            Nombre               = d.Nombre,
 6307            Situacion            = d.Situacion,
 6308            TieneItemsLiquidacion = d.TotalLiquidado != 0,
 6309            TotalLiquidado       = d.TotalLiquidado
 6310        }).ToList();
 2311    }
 312
 313    public async Task<byte[]> GenerarCsvNoDisponiblesAsync(long periodoId)
 314    {
 1315        var filas = await ObtenerNoDisponiblesAsync(periodoId);
 1316        var sb = new StringBuilder();
 1317        sb.AppendLine("Cédula;Nombre;Situación;Tiene Liquidación;Total Liquidado");
 318
 6319        foreach (var f in filas)
 2320            sb.AppendLine(
 2321                $"{f.Cedula};{f.Nombre};{f.Situacion};" +
 2322                $"{(f.TieneItemsLiquidacion ? "Sí" : "No")};{F(f.TotalLiquidado)}");
 323
 1324        return Encoding.UTF8.GetBytes(sb.ToString());
 1325    }
 326
 327    // ─── Helpers ─────────────────────────────────────────────────────────────
 328
 329    private static string F(decimal value) =>
 15330        value.ToString("F2", CultureInfo.InvariantCulture);
 331}