< Summary

Information
Class: FAU.Logica.Services.ReporteDeficitService
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Services/ReporteDeficitService.cs
Line coverage
89%
Covered lines: 171
Uncovered lines: 21
Coverable lines: 192
Total lines: 283
Line coverage: 89%
Branch coverage
68%
Covered branches: 11
Total branches: 16
Branch coverage: 68.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ObtenerDeficitPorPersonaAsync()100%11100%
BuildGrupoSituacion(...)100%11100%
BuildGrupoUnidad(...)100%11100%
BuildGrupoCompania(...)100%11100%
BuildPersona(...)100%11100%
GenerarCsvDeficitPorPersonaAsync()100%1010100%
ObtenerDeficitPorAcreedorAsync()100%11100%
GenerarCsvDeficitPorAcreedorAsync()16.66%14638.23%
FormatMonto(...)100%11100%

File(s)

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

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Globalization;
 3using System.Linq;
 4using System.Text;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using FAU.DataAccess.Repositories;
 8using FAU.Entidades;
 9using FAU.Logica.DTOs;
 10
 11namespace FAU.Logica.Services;
 12
 13public class ReporteDeficitService : IReporteDeficitService
 14{
 15    private readonly IReporteDeficitRepository _repo;
 16
 717    public ReporteDeficitService(IReporteDeficitRepository repo)
 18    {
 719        _repo = repo;
 720    }
 21
 22    // ─── Por Persona ─────────────────────────────────────────────────────────
 23
 24    public async Task<ReporteDeficitPorPersonaDto> ObtenerDeficitPorPersonaAsync(
 25        long periodoId, CancellationToken ct = default)
 26    {
 427        var filas = (await _repo.ObtenerPlanillaAjusteConRelacionAsync(periodoId, ct)).ToList();
 28
 429        var situaciones = filas
 430            .GroupBy(f => f.SituacionNombre)
 231            .OrderBy(g => g.Key)
 232            .Select(gSit => BuildGrupoSituacion(gSit.Key, gSit))
 433            .ToList();
 34
 435        return new ReporteDeficitPorPersonaDto
 436        {
 437            Situaciones    = situaciones,
 238            TotalSolicitado = situaciones.Sum(s => s.TotalSolicitado),
 239            TotalAplicado   = situaciones.Sum(s => s.TotalAplicado),
 240            TotalDeficit    = situaciones.Sum(s => s.TotalDeficit)
 441        };
 442    }
 43
 44    private static DeficitGrupoSituacionDto BuildGrupoSituacion(
 45        string situacion, IEnumerable<PlanillaAjusteConRelacionRow> filas)
 46    {
 247        var unidades = filas
 448            .GroupBy(f => f.UnidadNombre)
 249            .OrderBy(g => g.Key)
 250            .Select(gUni => BuildGrupoUnidad(gUni.Key, gUni))
 251            .ToList();
 52
 253        return new DeficitGrupoSituacionDto
 254        {
 255            Situacion       = situacion,
 256            Unidades        = unidades,
 257            TotalSolicitado = unidades.Sum(u => u.TotalSolicitado),
 258            TotalAplicado   = unidades.Sum(u => u.TotalAplicado),
 259            TotalDeficit    = unidades.Sum(u => u.TotalDeficit)
 260        };
 61    }
 62
 63    private static DeficitGrupoUnidadDto BuildGrupoUnidad(
 64        string unidad, IEnumerable<PlanillaAjusteConRelacionRow> filas)
 65    {
 266        var companias = filas
 467            .GroupBy(f => f.CompaniaNombre)
 268            .OrderBy(g => g.Key)
 269            .Select(gCia => BuildGrupoCompania(gCia.Key, gCia))
 270            .ToList();
 71
 272        return new DeficitGrupoUnidadDto
 273        {
 274            Unidad          = unidad,
 275            Companias       = companias,
 276            TotalSolicitado = companias.Sum(c => c.TotalSolicitado),
 277            TotalAplicado   = companias.Sum(c => c.TotalAplicado),
 278            TotalDeficit    = companias.Sum(c => c.TotalDeficit)
 279        };
 80    }
 81
 82    private static DeficitGrupoCompaniaDto BuildGrupoCompania(
 83        string compania, IEnumerable<PlanillaAjusteConRelacionRow> filas)
 84    {
 285        var personas = filas
 486            .GroupBy(f => new { f.PersonaId, f.Cedula, f.PersonaNombre })
 387            .OrderBy(g => g.Key.PersonaNombre)
 388            .Select(gPer => BuildPersona(gPer.Key.PersonaId, gPer.Key.Cedula, gPer.Key.PersonaNombre, gPer))
 289            .ToList();
 90
 291        return new DeficitGrupoCompaniaDto
 292        {
 293            Compania        = compania,
 294            Personas        = personas,
 395            TotalSolicitado = personas.Sum(p => p.TotalSolicitado),
 396            TotalAplicado   = personas.Sum(p => p.TotalAplicado),
 397            TotalDeficit    = personas.Sum(p => p.TotalDeficit)
 298        };
 99    }
 100
 101    private static DeficitPersonaDto BuildPersona(
 102        long personaId, string cedula, string nombre, IEnumerable<PlanillaAjusteConRelacionRow> filas)
 103    {
 3104        var acreedores = filas
 4105            .OrderBy(f => f.AcreedorNombre)
 4106            .Select(f => new DeficitAcreedorFilaDto
 4107            {
 4108                AcreedorId     = f.AcreedorId,
 4109                AcreedorCodigo = f.AcreedorCodigo,
 4110                AcreedorNombre = f.AcreedorNombre,
 4111                MontoSolicitado = f.MontoSolicitado,
 4112                MontoAplicado   = f.MontoAplicado,
 4113                MontoDeficit    = f.MontoNoAplicado
 4114            })
 3115            .ToList();
 116
 3117        return new DeficitPersonaDto
 3118        {
 3119            PersonaId       = personaId,
 3120            Cedula          = cedula,
 3121            Nombre          = nombre,
 3122            Acreedores      = acreedores,
 4123            TotalSolicitado = acreedores.Sum(a => a.MontoSolicitado),
 4124            TotalAplicado   = acreedores.Sum(a => a.MontoAplicado),
 4125            TotalDeficit    = acreedores.Sum(a => a.MontoDeficit)
 3126        };
 127    }
 128
 129    public async Task<byte[]> GenerarCsvDeficitPorPersonaAsync(
 130        long periodoId, CancellationToken ct = default)
 131    {
 2132        var dto = await ObtenerDeficitPorPersonaAsync(periodoId, ct);
 2133        var sb = new StringBuilder();
 2134        sb.AppendLine("Situación;Unidad;Compañía;Cédula;Nombre;Acreedor;Monto Solicitado;Monto Aplicado;Déficit");
 135
 6136        foreach (var gSit in dto.Situaciones)
 137        {
 4138            foreach (var gUni in gSit.Unidades)
 139            {
 4140                foreach (var gCia in gUni.Companias)
 141                {
 4142                    foreach (var persona in gCia.Personas)
 143                    {
 4144                        foreach (var acreedor in persona.Acreedores)
 145                        {
 1146                            sb.AppendLine(string.Join(";",
 1147                                gSit.Situacion,
 1148                                gUni.Unidad,
 1149                                gCia.Compania,
 1150                                persona.Cedula,
 1151                                persona.Nombre,
 1152                                acreedor.AcreedorNombre,
 1153                                FormatMonto(acreedor.MontoSolicitado),
 1154                                FormatMonto(acreedor.MontoAplicado),
 1155                                FormatMonto(acreedor.MontoDeficit)));
 156                        }
 157
 1158                        sb.AppendLine(string.Join(";",
 1159                            gSit.Situacion,
 1160                            gUni.Unidad,
 1161                            gCia.Compania,
 1162                            persona.Cedula,
 1163                            persona.Nombre,
 1164                            "TOTAL PERSONA",
 1165                            FormatMonto(persona.TotalSolicitado),
 1166                            FormatMonto(persona.TotalAplicado),
 1167                            FormatMonto(persona.TotalDeficit)));
 168                    }
 169                }
 170            }
 171        }
 172
 2173        sb.AppendLine(string.Join(";",
 2174            "", "", "", "", "",
 2175            "TOTAL GENERAL",
 2176            FormatMonto(dto.TotalSolicitado),
 2177            FormatMonto(dto.TotalAplicado),
 2178            FormatMonto(dto.TotalDeficit)));
 179
 2180        return Encoding.UTF8.GetBytes(sb.ToString());
 2181    }
 182
 183    // ─── Por Acreedor ─────────────────────────────────────────────────────────
 184
 185    public async Task<ReporteDeficitPorAcreedorDto> ObtenerDeficitPorAcreedorAsync(
 186        long periodoId, CancellationToken ct = default)
 187    {
 3188        var filas = (await _repo.ObtenerPlanillaAjusteConRelacionAsync(periodoId, ct)).ToList();
 189
 3190        var acreedores = filas
 2191            .GroupBy(f => new { f.AcreedorId, f.AcreedorCodigo, f.AcreedorNombre })
 2192            .OrderBy(g => g.Key.AcreedorNombre)
 3193            .Select(gAcr =>
 3194            {
 2195                var personas = gAcr
 2196                    .OrderBy(f => f.PersonaNombre)
 2197                    .Select(f => new DeficitPersonaAcreedorFilaDto
 2198                    {
 2199                        Cedula        = f.Cedula,
 2200                        Nombre        = f.PersonaNombre,
 2201                        Estado        = f.Estado,
 2202                        Solicitado    = f.MontoSolicitado,
 2203                        Descontado    = f.MontoAplicado,
 2204                        Deficit       = f.MontoNoAplicado,
 2205                        Diferencia    = f.MontoSolicitado - f.MontoAplicado,
 2206                        Observaciones = f.Observaciones
 2207                    })
 2208                    .ToList();
 3209
 2210                return new DeficitGrupoAcreedorDto
 2211                {
 2212                    AcreedorId      = gAcr.Key.AcreedorId,
 2213                    AcreedorCodigo  = gAcr.Key.AcreedorCodigo,
 2214                    AcreedorNombre  = gAcr.Key.AcreedorNombre,
 2215                    Personas        = personas,
 2216                    TotalSolicitado = personas.Sum(p => p.Solicitado),
 2217                    TotalDescontado = personas.Sum(p => p.Descontado),
 2218                    TotalDeficit    = personas.Sum(p => p.Deficit),
 2219                    TotalDiferencia = personas.Sum(p => p.Diferencia)
 2220                };
 3221            })
 3222            .ToList();
 223
 3224        return new ReporteDeficitPorAcreedorDto
 3225        {
 3226            Acreedores      = acreedores,
 2227            TotalSolicitado = acreedores.Sum(a => a.TotalSolicitado),
 2228            TotalDescontado = acreedores.Sum(a => a.TotalDescontado),
 2229            TotalDeficit    = acreedores.Sum(a => a.TotalDeficit),
 2230            TotalDiferencia = acreedores.Sum(a => a.TotalDiferencia)
 3231        };
 3232    }
 233
 234    public async Task<byte[]> GenerarCsvDeficitPorAcreedorAsync(
 235        long periodoId, CancellationToken ct = default)
 236    {
 1237        var dto = await ObtenerDeficitPorAcreedorAsync(periodoId, ct);
 1238        var sb = new StringBuilder();
 239        // Columnas en orden legacy: Solicit. → Déficit → Diferencia → Descont. → Obs. (SUM45037)
 1240        sb.AppendLine("Acreedor;Código Acreedor;Cédula;Nombre;Estado;Solicitado;Déficit;Diferencia;Descontado;Observacio
 241
 2242        foreach (var gAcr in dto.Acreedores)
 243        {
 0244            foreach (var persona in gAcr.Personas)
 245            {
 0246                sb.AppendLine(string.Join(";",
 0247                    gAcr.AcreedorNombre,
 0248                    gAcr.AcreedorCodigo,
 0249                    persona.Cedula,
 0250                    persona.Nombre,
 0251                    persona.Estado,
 0252                    FormatMonto(persona.Solicitado),
 0253                    FormatMonto(persona.Deficit),
 0254                    FormatMonto(persona.Diferencia),
 0255                    FormatMonto(persona.Descontado),
 0256                    persona.Observaciones ?? ""));
 257            }
 258
 0259            sb.AppendLine(string.Join(";",
 0260                gAcr.AcreedorNombre,
 0261                gAcr.AcreedorCodigo,
 0262                "", "SUBTOTAL", "",
 0263                FormatMonto(gAcr.TotalSolicitado),
 0264                FormatMonto(gAcr.TotalDeficit),
 0265                FormatMonto(gAcr.TotalDiferencia),
 0266                FormatMonto(gAcr.TotalDescontado),
 0267                ""));
 268        }
 269
 1270        sb.AppendLine(string.Join(";",
 1271            "", "", "", "TOTAL GENERAL", "",
 1272            FormatMonto(dto.TotalSolicitado),
 1273            FormatMonto(dto.TotalDeficit),
 1274            FormatMonto(dto.TotalDiferencia),
 1275            FormatMonto(dto.TotalDescontado),
 1276            ""));
 277
 1278        return Encoding.UTF8.GetBytes(sb.ToString());
 1279    }
 280
 281    private static string FormatMonto(decimal monto) =>
 16282        monto.ToString("F2", CultureInfo.InvariantCulture);
 283}