| | | 1 | | using System.Globalization; |
| | | 2 | | using System.Text; |
| | | 3 | | using FAU.DataAccess.Repositories; |
| | | 4 | | using FAU.Entidades; |
| | | 5 | | |
| | | 6 | | namespace FAU.Logica.Services; |
| | | 7 | | |
| | | 8 | | public class ReporteControlService : IReporteControlService |
| | | 9 | | { |
| | | 10 | | private readonly IReporteControlRepository _repo; |
| | | 11 | | |
| | 11 | 12 | | public ReporteControlService(IReporteControlRepository repo) |
| | | 13 | | { |
| | 11 | 14 | | _repo = repo; |
| | 11 | 15 | | } |
| | | 16 | | |
| | | 17 | | // ─── Cuadro de Efectivos Superior ─────────────────────────────────────── |
| | | 18 | | |
| | | 19 | | public async Task<CuadroEfectivosDto> ObtenerEfectivosSuperiorAsync( |
| | | 20 | | long periodoId, string? programa, string? regimen) |
| | | 21 | | { |
| | 3 | 22 | | var relaciones = await _repo.ObtenerRelacionesActivasAsync(); |
| | | 23 | | |
| | | 24 | | // Personal superior: oficiales (EsOficial == true) |
| | 3 | 25 | | var superior = relaciones |
| | 6 | 26 | | .Where(r => r.Grado.EsOficial) |
| | 5 | 27 | | .Where(r => FiltrarPrograma(r, programa)) |
| | 4 | 28 | | .Where(r => FiltrarRegimen(r, regimen)) |
| | 4 | 29 | | .Where(r => EsSituacionActividad(r)) |
| | 3 | 30 | | .ToList(); |
| | | 31 | | |
| | | 32 | | // Cuadro principal: agrupado por Grado × Escalafón |
| | 3 | 33 | | var filas = superior |
| | 4 | 34 | | .GroupBy(r => (GradoDenom: r.Grado.Denominacion, EscalafonDenom: r.Escalafon.Denominacion, Orden: r.Grado.Or |
| | 3 | 35 | | .OrderBy(g => g.Key.Orden) |
| | 3 | 36 | | .Select(g => new CuadroEfectivosFilaDto |
| | 3 | 37 | | { |
| | 3 | 38 | | Grado = g.Key.GradoDenom, |
| | 3 | 39 | | Escalafon = g.Key.EscalafonDenom, |
| | 4 | 40 | | EnCuadro = g.Count(r => r.Situacion.Calculador == "Sit10Calculator" || r.Situacion.Calculador == "SitC |
| | 4 | 41 | | FueraCuadro = g.Count(r => r.Situacion.Calculador == "Sit30Calculator") |
| | 3 | 42 | | }) |
| | 3 | 43 | | .ToList(); |
| | | 44 | | |
| | | 45 | | // Totales por escalafón |
| | 3 | 46 | | var totalesEscalafon = filas |
| | 3 | 47 | | .GroupBy(f => f.Escalafon) |
| | 3 | 48 | | .Select(g => new CuadroEfectivosTotalesEscalafonDto |
| | 3 | 49 | | { |
| | 3 | 50 | | Escalafon = g.Key, |
| | 3 | 51 | | Total = g.Sum(f => f.Total) |
| | 3 | 52 | | }) |
| | 3 | 53 | | .ToList(); |
| | | 54 | | |
| | | 55 | | // Cuadro secundario: reincorporados, equiparados, reservistas |
| | 3 | 56 | | var secundarioGrupos = relaciones |
| | 6 | 57 | | .Where(r => r.Grado.EsOficial) |
| | 5 | 58 | | .Where(r => FiltrarPrograma(r, programa)) |
| | 4 | 59 | | .Where(r => FiltrarRegimen(r, regimen)) |
| | 4 | 60 | | .Where(r => EsSituacionSecundariaSuperior(r)) |
| | 0 | 61 | | .GroupBy(r => (r.Grado.Denominacion, r.Grado.Orden)) |
| | 0 | 62 | | .OrderBy(g => g.Key.Orden) |
| | 0 | 63 | | .Select(g => new CuadroEfectivosSecundarioFilaDto |
| | 0 | 64 | | { |
| | 0 | 65 | | Grado = g.Key.Denominacion, |
| | 0 | 66 | | Reincorporados = g.Count(r => EsReincorporado(r)), |
| | 0 | 67 | | Equiparados = g.Count(r => EsEquiparado(r)), |
| | 0 | 68 | | Reservistas = g.Count(r => EsReservista(r)) |
| | 0 | 69 | | }) |
| | 3 | 70 | | .ToList(); |
| | | 71 | | |
| | 3 | 72 | | return new CuadroEfectivosDto |
| | 3 | 73 | | { |
| | 3 | 74 | | Filas = filas, |
| | 3 | 75 | | TotalesPorEscalafon = totalesEscalafon, |
| | 3 | 76 | | TotalGeneral = filas.Sum(f => f.Total), |
| | 3 | 77 | | CuadroSecundario = secundarioGrupos |
| | 3 | 78 | | }; |
| | 3 | 79 | | } |
| | | 80 | | |
| | | 81 | | public async Task<byte[]> GenerarCsvEfectivosSuperiorAsync( |
| | | 82 | | long periodoId, string? programa, string? regimen) |
| | | 83 | | { |
| | 1 | 84 | | var dto = await ObtenerEfectivosSuperiorAsync(periodoId, programa, regimen); |
| | | 85 | | |
| | 1 | 86 | | var sb = new StringBuilder(); |
| | 1 | 87 | | sb.AppendLine("Grado;Escalafón;En Cuadro;Fuera de Cuadro;Total"); |
| | | 88 | | |
| | 4 | 89 | | foreach (var fila in dto.Filas) |
| | 1 | 90 | | sb.AppendLine($"{fila.Grado};{fila.Escalafon};{fila.EnCuadro};{fila.FueraCuadro};{fila.Total}"); |
| | | 91 | | |
| | 1 | 92 | | return Encoding.UTF8.GetBytes(sb.ToString()); |
| | 1 | 93 | | } |
| | | 94 | | |
| | | 95 | | // ─── Cuadro de Efectivos Subalterno ───────────────────────────────────── |
| | | 96 | | |
| | | 97 | | public async Task<CuadroEfectivosSubalternoDto> ObtenerEfectivosSubalternoAsync( |
| | | 98 | | long periodoId, string? programa, string? regimen) |
| | | 99 | | { |
| | 3 | 100 | | var relaciones = await _repo.ObtenerRelacionesActivasAsync(); |
| | | 101 | | |
| | | 102 | | // Personal subalterno: grados 1–7, cadetes, aprendices (EsSubalterno == true) |
| | 3 | 103 | | var subalterno = relaciones |
| | 6 | 104 | | .Where(r => r.Grado.EsSubalterno) |
| | 5 | 105 | | .Where(r => FiltrarPrograma(r, programa)) |
| | 5 | 106 | | .Where(r => FiltrarRegimen(r, regimen)) |
| | 4 | 107 | | .Where(r => EsSituacionActividad(r)) |
| | 3 | 108 | | .ToList(); |
| | | 109 | | |
| | 3 | 110 | | var filas = subalterno |
| | 4 | 111 | | .GroupBy(r => (r.Grado.Denominacion, r.Grado.Orden)) |
| | 3 | 112 | | .OrderBy(g => g.Key.Orden) |
| | 3 | 113 | | .Select(g => new CuadroEfectivosSubalternoFilaDto |
| | 3 | 114 | | { |
| | 3 | 115 | | Grado = g.Key.Denominacion, |
| | 3 | 116 | | Efectivos = g.Count(), |
| | 3 | 117 | | Asignados = 0 // TODO: cargar desde tabla de plazas presupuestales cuando esté disponible |
| | 3 | 118 | | }) |
| | 3 | 119 | | .ToList(); |
| | | 120 | | |
| | | 121 | | // Cuadro secundario: en reserva, reincorporados, civiles equiparados |
| | 3 | 122 | | var secundario = relaciones |
| | 6 | 123 | | .Where(r => r.Grado.EsSubalterno) |
| | 5 | 124 | | .Where(r => FiltrarPrograma(r, programa)) |
| | 5 | 125 | | .Where(r => FiltrarRegimen(r, regimen)) |
| | 4 | 126 | | .Where(r => EsSituacionSecundariaSubalterno(r)) |
| | 0 | 127 | | .GroupBy(r => (r.Grado.Denominacion, r.Grado.Orden)) |
| | 0 | 128 | | .OrderBy(g => g.Key.Orden) |
| | 0 | 129 | | .Select(g => new CuadroEfectivosSubalternoSecundarioFilaDto |
| | 0 | 130 | | { |
| | 0 | 131 | | Grado = g.Key.Denominacion, |
| | 0 | 132 | | EnReserva = g.Count(r => EsReservista(r)), |
| | 0 | 133 | | Reincorporados = g.Count(r => EsReincorporado(r)), |
| | 0 | 134 | | Equiparados = g.Count(r => EsEquiparado(r)) |
| | 0 | 135 | | }) |
| | 3 | 136 | | .ToList(); |
| | | 137 | | |
| | 3 | 138 | | return new CuadroEfectivosSubalternoDto |
| | 3 | 139 | | { |
| | 3 | 140 | | Filas = filas, |
| | 3 | 141 | | TotalEfectivos = filas.Sum(f => f.Efectivos), |
| | 3 | 142 | | TotalAsignados = filas.Sum(f => f.Asignados), |
| | 3 | 143 | | CuadroSecundario = secundario |
| | 3 | 144 | | }; |
| | 3 | 145 | | } |
| | | 146 | | |
| | | 147 | | public async Task<byte[]> GenerarCsvEfectivosSubalternoAsync( |
| | | 148 | | long periodoId, string? programa, string? regimen) |
| | | 149 | | { |
| | 1 | 150 | | var dto = await ObtenerEfectivosSubalternoAsync(periodoId, programa, regimen); |
| | | 151 | | |
| | 1 | 152 | | var sb = new StringBuilder(); |
| | 1 | 153 | | sb.AppendLine("Grado;Efectivos;Asignados;Diferencia"); |
| | | 154 | | |
| | 4 | 155 | | foreach (var fila in dto.Filas) |
| | 1 | 156 | | sb.AppendLine($"{fila.Grado};{fila.Efectivos};{fila.Asignados};{fila.Diferencia}"); |
| | | 157 | | |
| | 1 | 158 | | return Encoding.UTF8.GetBytes(sb.ToString()); |
| | 1 | 159 | | } |
| | | 160 | | |
| | | 161 | | // ─── Listín de Contralor ───────────────────────────────────────────────── |
| | | 162 | | |
| | | 163 | | public async Task<ListinContralorDto> ObtenerListinAsync( |
| | | 164 | | long periodoId, int? situacionDesde, int? situacionHasta) |
| | | 165 | | { |
| | 3 | 166 | | var items = await _repo.ObtenerItemsLiquidacionAsync(periodoId); |
| | 3 | 167 | | var relaciones = await _repo.ObtenerRelacionesActivasAsync(); |
| | | 168 | | |
| | 3 | 169 | | var relPorCedula = relaciones |
| | 4 | 170 | | .GroupBy(r => r.Persona.Cedula) |
| | 11 | 171 | | .ToDictionary(g => g.Key, g => g.First()); |
| | | 172 | | |
| | | 173 | | // Agrupar items por cédula |
| | 3 | 174 | | var itemsPorCedula = items |
| | 7 | 175 | | .GroupBy(i => i.Cedula) |
| | 11 | 176 | | .ToDictionary(g => g.Key, g => g.ToList()); |
| | | 177 | | |
| | | 178 | | // Agrupar cédulas por situación |
| | 3 | 179 | | var porSituacion = new Dictionary<string, (Situacion Sit, List<(RelacionLaboral Rel, List<LiquidacionItem> Items |
| | | 180 | | |
| | 14 | 181 | | foreach (var (cedula, itemsList) in itemsPorCedula) |
| | | 182 | | { |
| | 4 | 183 | | if (!relPorCedula.TryGetValue(cedula, out var rel)) |
| | | 184 | | continue; |
| | | 185 | | |
| | 4 | 186 | | var sit = rel.Situacion; |
| | | 187 | | |
| | | 188 | | // Filtrar por rango de situación (se extrae el número del código, ej: "SIT10" → 10) |
| | 4 | 189 | | var numCodigo = ExtraerNumeroSituacion(sit.Codigo); |
| | 4 | 190 | | if (situacionDesde.HasValue && numCodigo < situacionDesde.Value) |
| | | 191 | | continue; |
| | 3 | 192 | | if (situacionHasta.HasValue && numCodigo > situacionHasta.Value) |
| | | 193 | | continue; |
| | | 194 | | |
| | 3 | 195 | | if (!porSituacion.TryGetValue(sit.Codigo, out var entry)) |
| | | 196 | | { |
| | 3 | 197 | | entry = (sit, new List<(RelacionLaboral, List<LiquidacionItem>)>()); |
| | 3 | 198 | | porSituacion[sit.Codigo] = entry; |
| | | 199 | | } |
| | 3 | 200 | | entry.Funcs.Add((rel, itemsList)); |
| | | 201 | | } |
| | | 202 | | |
| | 3 | 203 | | var listaSituaciones = new List<ListinSituacionDto>(); |
| | | 204 | | |
| | 15 | 205 | | foreach (var (codigo, (sit, funcs)) in porSituacion.OrderBy(kvp => ExtraerNumeroSituacion(kvp.Key))) |
| | | 206 | | { |
| | 3 | 207 | | var funcionarios = funcs.Select(f => |
| | 3 | 208 | | { |
| | 9 | 209 | | var haberes = f.Items.Where(i => EsHaber(i)).Select(MapItem).ToList(); |
| | 9 | 210 | | var beneficios = f.Items.Where(i => EsBeneficio(i)).Select(MapItem).ToList(); |
| | 9 | 211 | | var descuentos = f.Items.Where(i => EsDescuento(i)).Select(MapItem).ToList(); |
| | 3 | 212 | | |
| | 6 | 213 | | var nominal = haberes.Sum(h => h.Importe); |
| | 4 | 214 | | var totalBen = beneficios.Sum(b => b.Importe); |
| | 5 | 215 | | var totalDesc = Math.Abs(descuentos.Sum(d => d.Importe)); |
| | 3 | 216 | | var montepio = Math.Abs(descuentos |
| | 2 | 217 | | .Where(d => d.NombreConcepto.Contains("MONTEPIO", StringComparison.OrdinalIgnoreCase)) |
| | 5 | 218 | | .Sum(d => d.Importe)); |
| | 3 | 219 | | var liquido = nominal + totalBen - totalDesc; |
| | 3 | 220 | | |
| | 3 | 221 | | return new ListinFuncionarioDto |
| | 3 | 222 | | { |
| | 3 | 223 | | Cedula = f.Rel.Persona.Cedula, |
| | 3 | 224 | | Nombre = f.Rel.Persona.NombreCompleto, |
| | 3 | 225 | | Grado = f.Rel.Grado.Denominacion, |
| | 3 | 226 | | Escalafon = f.Rel.Escalafon.Denominacion, |
| | 3 | 227 | | Haberes = haberes, |
| | 3 | 228 | | Beneficios = beneficios, |
| | 3 | 229 | | Descuentos = descuentos, |
| | 3 | 230 | | Totales = new ListinTotalesDto |
| | 3 | 231 | | { |
| | 3 | 232 | | Nominal = nominal, |
| | 3 | 233 | | Montepio = montepio, |
| | 3 | 234 | | Descuentos = totalDesc, |
| | 3 | 235 | | Liquido = liquido |
| | 3 | 236 | | } |
| | 3 | 237 | | }; |
| | 3 | 238 | | }).ToList(); |
| | | 239 | | |
| | 3 | 240 | | var subtotales = new ListinTotalesDto |
| | 3 | 241 | | { |
| | 3 | 242 | | Nominal = funcionarios.Sum(f => f.Totales.Nominal), |
| | 3 | 243 | | Montepio = funcionarios.Sum(f => f.Totales.Montepio), |
| | 3 | 244 | | Descuentos = funcionarios.Sum(f => f.Totales.Descuentos), |
| | 3 | 245 | | Liquido = funcionarios.Sum(f => f.Totales.Liquido) |
| | 3 | 246 | | }; |
| | | 247 | | |
| | 3 | 248 | | listaSituaciones.Add(new ListinSituacionDto |
| | 3 | 249 | | { |
| | 3 | 250 | | Situacion = sit.Codigo, |
| | 3 | 251 | | NombreSituacion = sit.Denominacion, |
| | 3 | 252 | | Funcionarios = funcionarios, |
| | 3 | 253 | | Subtotales = subtotales |
| | 3 | 254 | | }); |
| | | 255 | | } |
| | | 256 | | |
| | 3 | 257 | | var resumen = new ListinTotalesDto |
| | 3 | 258 | | { |
| | 3 | 259 | | Nominal = listaSituaciones.Sum(s => s.Subtotales.Nominal), |
| | 3 | 260 | | Montepio = listaSituaciones.Sum(s => s.Subtotales.Montepio), |
| | 3 | 261 | | Descuentos = listaSituaciones.Sum(s => s.Subtotales.Descuentos), |
| | 3 | 262 | | Liquido = listaSituaciones.Sum(s => s.Subtotales.Liquido) |
| | 3 | 263 | | }; |
| | | 264 | | |
| | 3 | 265 | | return new ListinContralorDto |
| | 3 | 266 | | { |
| | 3 | 267 | | PorSituacion = listaSituaciones, |
| | 3 | 268 | | ResumenFinal = resumen |
| | 3 | 269 | | }; |
| | 3 | 270 | | } |
| | | 271 | | |
| | | 272 | | public async Task<byte[]> GenerarCsvListinAsync( |
| | | 273 | | long periodoId, int? situacionDesde, int? situacionHasta) |
| | | 274 | | { |
| | 1 | 275 | | var dto = await ObtenerListinAsync(periodoId, situacionDesde, situacionHasta); |
| | | 276 | | |
| | 1 | 277 | | var sb = new StringBuilder(); |
| | 1 | 278 | | sb.AppendLine("Situación;Cédula;Nombre;Grado;Escalafón;Código Concepto;Rubro;Importe"); |
| | | 279 | | |
| | 4 | 280 | | foreach (var sit in dto.PorSituacion) |
| | | 281 | | { |
| | 4 | 282 | | foreach (var func in sit.Funcionarios) |
| | | 283 | | { |
| | 6 | 284 | | foreach (var item in func.Haberes.Concat(func.Descuentos)) |
| | | 285 | | { |
| | 2 | 286 | | sb.AppendLine($"{sit.Situacion};{func.Cedula};{func.Nombre};" + |
| | 2 | 287 | | $"{func.Grado};{func.Escalafon};" + |
| | 2 | 288 | | $"{item.CodigoConcepto};{item.NombreConcepto};{F(item.Importe)}"); |
| | | 289 | | } |
| | | 290 | | } |
| | | 291 | | |
| | 1 | 292 | | sb.AppendLine($"SUBTOTAL;{sit.Situacion};;;;;;" + |
| | 1 | 293 | | $"{F(sit.Subtotales.Liquido)}"); |
| | | 294 | | } |
| | | 295 | | |
| | 1 | 296 | | sb.AppendLine($"TOTAL;;;;;;;{F(dto.ResumenFinal.Liquido)}"); |
| | | 297 | | |
| | 1 | 298 | | return Encoding.UTF8.GetBytes(sb.ToString()); |
| | 1 | 299 | | } |
| | | 300 | | |
| | | 301 | | // ─── Comparativo SGH ───────────────────────────────────────────────────── |
| | | 302 | | |
| | | 303 | | public async Task<ComparativoSghDto> ObtenerComparativoSghAsync( |
| | | 304 | | long periodoId, List<PadronSghEntradaDto> filas) |
| | | 305 | | { |
| | 2 | 306 | | var relaciones = await _repo.ObtenerRelacionesActivasAsync(); |
| | | 307 | | |
| | 7 | 308 | | var sghPorCedula = filas.ToDictionary(p => p.Cedula); |
| | 2 | 309 | | var sistemaPorCedula = relaciones |
| | 5 | 310 | | .GroupBy(r => r.Persona.Cedula) |
| | 12 | 311 | | .ToDictionary(g => g.Key, g => g.First()); |
| | | 312 | | |
| | 2 | 313 | | var soloEnSistema = new List<ComparativoSoloSistemaDto>(); |
| | 2 | 314 | | var soloEnSgh = new List<ComparativoSoloSghDto>(); |
| | 2 | 315 | | var diferencias = new List<ComparativoDiferenciaDto>(); |
| | 2 | 316 | | int coincidencias = 0; |
| | | 317 | | |
| | | 318 | | // Cédulas en el sistema |
| | 14 | 319 | | foreach (var (cedula, rel) in sistemaPorCedula) |
| | | 320 | | { |
| | 5 | 321 | | if (!sghPorCedula.TryGetValue(cedula, out var sghFila)) |
| | | 322 | | { |
| | 2 | 323 | | soloEnSistema.Add(new ComparativoSoloSistemaDto |
| | 2 | 324 | | { |
| | 2 | 325 | | Cedula = cedula, |
| | 2 | 326 | | Nombre = rel.Persona.NombreCompleto, |
| | 2 | 327 | | Situacion = rel.Situacion.Codigo, |
| | 2 | 328 | | Grado = rel.Grado.Codigo |
| | 2 | 329 | | }); |
| | | 330 | | } |
| | | 331 | | else |
| | | 332 | | { |
| | 3 | 333 | | bool mismaSituacion = rel.Situacion.Codigo == sghFila.SituacionCodigo; |
| | 3 | 334 | | bool mismoGrado = rel.Grado.Codigo == sghFila.GradoCodigo; |
| | | 335 | | |
| | 3 | 336 | | if (mismaSituacion && mismoGrado) |
| | | 337 | | { |
| | 2 | 338 | | coincidencias++; |
| | | 339 | | } |
| | | 340 | | else |
| | | 341 | | { |
| | 1 | 342 | | diferencias.Add(new ComparativoDiferenciaDto |
| | 1 | 343 | | { |
| | 1 | 344 | | Cedula = cedula, |
| | 1 | 345 | | Nombre = rel.Persona.NombreCompleto, |
| | 1 | 346 | | SituacionSistema = rel.Situacion.Codigo, |
| | 1 | 347 | | SituacionSgh = sghFila.SituacionCodigo, |
| | 1 | 348 | | GradoSistema = rel.Grado.Codigo, |
| | 1 | 349 | | GradoSgh = sghFila.GradoCodigo |
| | 1 | 350 | | }); |
| | | 351 | | } |
| | | 352 | | } |
| | | 353 | | } |
| | | 354 | | |
| | | 355 | | // Cédulas solo en SGH |
| | 14 | 356 | | foreach (var (cedula, sghFila) in sghPorCedula) |
| | | 357 | | { |
| | 5 | 358 | | if (!sistemaPorCedula.ContainsKey(cedula)) |
| | | 359 | | { |
| | 2 | 360 | | soloEnSgh.Add(new ComparativoSoloSghDto |
| | 2 | 361 | | { |
| | 2 | 362 | | Cedula = cedula, |
| | 2 | 363 | | SituacionCodigo = sghFila.SituacionCodigo, |
| | 2 | 364 | | GradoCodigo = sghFila.GradoCodigo |
| | 2 | 365 | | }); |
| | | 366 | | } |
| | | 367 | | } |
| | | 368 | | |
| | 2 | 369 | | return new ComparativoSghDto |
| | 2 | 370 | | { |
| | 2 | 371 | | SoloEnSistema = soloEnSistema, |
| | 2 | 372 | | SoloEnSgh = soloEnSgh, |
| | 2 | 373 | | Diferencias = diferencias, |
| | 2 | 374 | | TotalCoincidencias = coincidencias |
| | 2 | 375 | | }; |
| | 2 | 376 | | } |
| | | 377 | | |
| | | 378 | | public async Task<byte[]> GenerarCsvComparativoSghAsync( |
| | | 379 | | long periodoId, List<PadronSghEntradaDto> filas) |
| | | 380 | | { |
| | 1 | 381 | | var dto = await ObtenerComparativoSghAsync(periodoId, filas); |
| | | 382 | | |
| | 1 | 383 | | var sb = new StringBuilder(); |
| | 1 | 384 | | sb.AppendLine("Tipo;Cédula;Nombre;Situación Sistema;Situación SGH;Grado Sistema;Grado SGH"); |
| | | 385 | | |
| | 4 | 386 | | foreach (var r in dto.SoloEnSistema) |
| | 1 | 387 | | sb.AppendLine($"SOLO_SISTEMA;{r.Cedula};{r.Nombre};{r.Situacion};;{r.Grado};"); |
| | | 388 | | |
| | 4 | 389 | | foreach (var r in dto.SoloEnSgh) |
| | 1 | 390 | | sb.AppendLine($"SOLO_SGH;{r.Cedula};;;{r.SituacionCodigo};;{r.GradoCodigo}"); |
| | | 391 | | |
| | 2 | 392 | | foreach (var r in dto.Diferencias) |
| | 0 | 393 | | sb.AppendLine($"DIFERENCIA;{r.Cedula};{r.Nombre};{r.SituacionSistema};{r.SituacionSgh};{r.GradoSistema};{r.G |
| | | 394 | | |
| | 1 | 395 | | return Encoding.UTF8.GetBytes(sb.ToString()); |
| | 1 | 396 | | } |
| | | 397 | | |
| | | 398 | | // ─── Helpers privados ──────────────────────────────────────────────────── |
| | | 399 | | |
| | | 400 | | private static bool FiltrarPrograma(RelacionLaboral r, string? programa) |
| | | 401 | | { |
| | 20 | 402 | | if (string.IsNullOrEmpty(programa)) |
| | 16 | 403 | | return true; |
| | 4 | 404 | | return r.Programa.Codigo == programa; |
| | | 405 | | } |
| | | 406 | | |
| | | 407 | | private static bool FiltrarRegimen(RelacionLaboral r, string? regimen) |
| | | 408 | | { |
| | 18 | 409 | | if (string.IsNullOrEmpty(regimen)) |
| | 14 | 410 | | return true; |
| | 4 | 411 | | return regimen switch |
| | 4 | 412 | | { |
| | 0 | 413 | | "ley-vieja" => r.Regimen.EsLeyVieja, |
| | 4 | 414 | | "ley-nueva" => !r.Regimen.EsLeyVieja, |
| | 0 | 415 | | _ => true |
| | 4 | 416 | | }; |
| | | 417 | | } |
| | | 418 | | |
| | | 419 | | private static bool EsSituacionActividad(RelacionLaboral r) => |
| | 8 | 420 | | r.Situacion.Calculador is "Sit10Calculator" or "Sit30Calculator" or "SitCadeteCalculator"; |
| | | 421 | | |
| | | 422 | | private static bool EsSituacionSecundariaSuperior(RelacionLaboral r) => |
| | 4 | 423 | | EsReincorporado(r) || EsEquiparado(r) || EsReservista(r); |
| | | 424 | | |
| | | 425 | | private static bool EsSituacionSecundariaSubalterno(RelacionLaboral r) => |
| | 4 | 426 | | EsReservista(r) || EsReincorporado(r) || EsEquiparado(r); |
| | | 427 | | |
| | | 428 | | private static bool EsReincorporado(RelacionLaboral r) => |
| | 8 | 429 | | r.Situacion.Calculador is "Sit50Calculator"; |
| | | 430 | | |
| | | 431 | | private static bool EsEquiparado(RelacionLaboral r) => |
| | 8 | 432 | | r.Situacion.Calculador is "Sit70Calculator" or "CivilCalculator"; |
| | | 433 | | |
| | | 434 | | private static bool EsReservista(RelacionLaboral r) => |
| | 8 | 435 | | r.Situacion.Calculador is "ReservaCalculator" or "ReservaSuperiorCalculator"; |
| | | 436 | | |
| | | 437 | | private static int ExtraerNumeroSituacion(string codigo) |
| | | 438 | | { |
| | | 439 | | // "SIT10" → 10, "SIT07" → 7, etc. |
| | 7 | 440 | | var num = new string(codigo.Where(char.IsDigit).ToArray()); |
| | 7 | 441 | | return int.TryParse(num, out var n) ? n : 0; |
| | | 442 | | } |
| | | 443 | | |
| | | 444 | | private static bool EsHaber(LiquidacionItem i) => |
| | 6 | 445 | | i.RubroContable is "HabNorGrab" or "HabsAnGrab" or "HabsNoGrab"; |
| | | 446 | | |
| | | 447 | | private static bool EsBeneficio(LiquidacionItem i) => |
| | 6 | 448 | | i.RubroContable is "BenSocGrab" or "BenSocNoGr"; |
| | | 449 | | |
| | | 450 | | private static bool EsDescuento(LiquidacionItem i) => |
| | 6 | 451 | | i.RubroContable is "DtoLegGrab" or "DtoLegNoGr" or "DtoPerGrab"; |
| | | 452 | | |
| | 6 | 453 | | private static ListinItemDto MapItem(LiquidacionItem i) => new() |
| | 6 | 454 | | { |
| | 6 | 455 | | CodigoConcepto = i.CodigoConcepto, |
| | 6 | 456 | | NombreConcepto = i.NombreConcepto, |
| | 6 | 457 | | Importe = i.Importe |
| | 6 | 458 | | }; |
| | | 459 | | |
| | | 460 | | private static string F(decimal value) => |
| | 4 | 461 | | value.ToString("F2", CultureInfo.InvariantCulture); |
| | | 462 | | } |