< Summary

Information
Class: FAU.Logica.Importadores.DescuentoPersonalTxtLineParser
Assembly: FAU.Logica
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Importadores/DescuentoPersonalTxtLineParser.cs
Line coverage
86%
Covered lines: 25
Uncovered lines: 4
Coverable lines: 29
Total lines: 72
Line coverage: 86.2%
Branch coverage
81%
Covered branches: 13
Total branches: 16
Branch coverage: 81.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
TryParse(...)83.33%121285.71%
EsNumerico(...)75%44100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.Logica/Importadores/DescuentoPersonalTxtLineParser.cs

#LineLine coverage
 1namespace FAU.Logica.Importadores;
 2
 3/// <summary>
 4/// Fila parseada de un archivo de ancho fijo (formato legacy FoxPro) de descuentos personales.
 5/// </summary>
 6public sealed record DescuentoPersonalTxtFila(int NumeroLinea, int CodigoConcepto, string CedulaSinDigito, decimal Impor
 7
 8/// <summary>
 9/// Parsea líneas de ancho fijo (25 caracteres) enviadas por los acreedores para la carga
 10/// masiva de descuentos personales. Layout: [0,2) indicador literal "01",
 11/// [2,6) código de descuento (4 dígitos), [6,13) cédula sin dígito verificador (7 dígitos),
 12/// [13,25) importe*100 zero-padded (los últimos 2 dígitos son los decimales).
 13/// </summary>
 14public static class DescuentoPersonalTxtLineParser
 15{
 16    private const int LargoLinea = 25;
 17    private const string IndicadorEsperado = "01";
 18
 19    public static bool TryParse(string linea, int numeroLinea, out DescuentoPersonalTxtFila? fila, out string? error)
 20    {
 1421        fila = null;
 1422        error = null;
 23
 1424        var contenido = linea.TrimEnd('\r', '\n');
 25
 1426        if (contenido.Length != LargoLinea)
 27        {
 128            error = $"Longitud de línea inválida (esperado {LargoLinea}, recibido {contenido.Length}).";
 129            return false;
 30        }
 31
 1332        var indicador = contenido.Substring(0, 2);
 1333        if (indicador != IndicadorEsperado)
 34        {
 135            error = $"Indicador de registro '{indicador}' no soportado (se esperaba '{IndicadorEsperado}').";
 136            return false;
 37        }
 38
 1239        var codigoTexto = contenido.Substring(2, 4);
 1240        if (!EsNumerico(codigoTexto))
 41        {
 042            error = $"El código de descuento '{codigoTexto}' no es numérico.";
 043            return false;
 44        }
 45
 1246        var cedula = contenido.Substring(6, 7);
 1247        if (!EsNumerico(cedula))
 48        {
 149            error = $"La cédula '{cedula}' no es numérica.";
 150            return false;
 51        }
 52
 1153        var montoTexto = contenido.Substring(13, 12);
 1154        if (!EsNumerico(montoTexto))
 55        {
 056            error = $"El importe '{montoTexto}' no es numérico.";
 057            return false;
 58        }
 59
 1160        var importe = long.Parse(montoTexto) / 100m;
 1161        if (importe <= 0)
 62        {
 163            error = "El importe debe ser mayor a cero.";
 164            return false;
 65        }
 66
 1067        fila = new DescuentoPersonalTxtFila(numeroLinea, int.Parse(codigoTexto), cedula, importe);
 1068        return true;
 69    }
 70
 3571    private static bool EsNumerico(string texto) => texto.Length > 0 && texto.All(char.IsDigit);
 72}