Está en la página 1de 7

/// <summary> /// Representa un nmero.

En la clase se desglosan las distintas opciones que se puedan /// encontrar /// </summary> public class NumeroNif { /// <summary> /// Tipos de Cdigos. /// </summary> /// <remarks>Aunque actualmente no se utilice el trmino CIF, se usa en la enumeracin /// por comodidad</remarks> private enum TiposCodigosEnum { NIF, NIE, CIF } // Nmero tal cual lo introduce el usuario private string numero; private TiposCodigosEnum tipo; /// <summary> /// Parte de Nif: En caso de ser un Nif intracomunitario, permite obtener el cgido del pas /// </summary> public string CodigoIntracomunitario { get; internal set; } internal bool EsIntraComunitario { get; set; } /// <summary> /// Parte de Nif: Letra inicial del Nif, en caso de tenerla /// </summary> public string LetraInicial { get; internal set; } /// <summary> /// Parte de Nif: Bloque numrico del NIF. En el caso de un NIF de persona fsica, /// corresponder al DNI /// </summary> public int Numero { get; internal set; } /// <summary> /// Parte de Nif: Dgito de control. Puede ser nmero o letra /// </summary> public string DigitoControl { get; internal set; } /// <summary> /// Valor que representa si el Nif introducido es correcto /// </summary> public bool EsCorrecto { get; internal set; } /// <summary> /// Cadena que representa el tipo de Nif comprobado: /// - NIF : Nmero de identificacin fiscal de persona fsica

/// - NIE : Nmero de identificacin fiscal extranjera /// - CIF : Cdigo de identificacin fiscal (Entidad jurdica) /// </summary> public string TipoNif { get { return tipo.ToString(); } } /// <summary> /// Constructor. Al instanciar la clase se realizan todos los clculos /// </summary> /// <param name="numero">Cadena de 9 u 11 caracteres que contiene el DNI/NIF /// tal cual lo ha introducido el usuario para su verificacin</param> private NumeroNif(string numero) { // Se eliminan los carcteres sobrantes numero = EliminaCaracteres(numero); // Todo en mausculas numero = numero.ToUpper(); // Comprobacin bsica de la cadena introducida por el usuario if (numero.Length != 9 && numero.Length != 11) throw new ArgumentException("El NIF no tiene un nmero de caracteres vlidos"); this.numero = numero; Desglosa(); switch (tipo) { case TiposCodigosEnum.NIF: case TiposCodigosEnum.NIE: this.EsCorrecto = CompruebaNif(); break; case TiposCodigosEnum.CIF: this.EsCorrecto = CompruebaCif(); break; } } #region Preparacin del nmero (desglose) /// <summary> /// Realiza un desglose del nmero introducido por el usuario en las propiedades /// de la clase /// </summary> private void Desglosa() {

Int32 n; if (numero.Length == 11) { // Nif Intracomunitario EsIntraComunitario = true; CodigoIntracomunitario = numero.Substring(0, 2); LetraInicial = numero.Substring(2, 1); Int32.TryParse(numero.Substring(3, 7), out n); DigitoControl = numero.Substring(10, 1); tipo = GetTipoDocumento(LetraInicial[0]); } else { // Nif espaol tipo = GetTipoDocumento(numero[0]); EsIntraComunitario = false; if (tipo == TiposCodigosEnum.NIF) { LetraInicial = string.Empty; Int32.TryParse(numero.Substring(0, 8), out n); } else { LetraInicial = numero.Substring(0, 1); Int32.TryParse(numero.Substring(1, 7), out n); } DigitoControl = numero.Substring(8, 1); } Numero = n; } /// <summary> /// En base al primer carcter del cdigo, se obtiene el tipo de documento que se intenta /// comprobar /// </summary> /// <param name="letra">Primer carcter del nmero pasado</param> /// <returns>Tipo de documento</returns> private TiposCodigosEnum GetTipoDocumento(char letra) { Regex regexNumeros = new Regex("[0-9]"); if (regexNumeros.IsMatch(letra.ToString())) return TiposCodigosEnum.NIF; Regex regexLetrasNIE = new Regex("[XYZ]"); if (regexLetrasNIE.IsMatch(letra.ToString())) return TiposCodigosEnum.NIE;

Regex regexLetrasCIF = new Regex("[ABCDEFGHJPQRSUVNW]"); if (regexLetrasCIF.IsMatch(letra.ToString())) return TiposCodigosEnum.CIF; throw new ApplicationException("El cdigo no es reconocible"); }

/// <summary> /// Eliminacin de todos los carcteres no numricos o de texto de la cadena /// </summary> /// <param name="numero">Nmero tal cual lo escribe el usuario</param> /// <returns>Cadena de 9 u 11 carcteres sin signos</returns> private string EliminaCaracteres(string numero) { // Todos los carcteres que no sean nmeros o letras string caracteres = @"[^\w]"; Regex regex = new Regex(caracteres); return regex.Replace(numero, ""); } #endregion #region Clculos private bool CompruebaNif() { return DigitoControl == GetLetraNif(); } /// <summary> /// Clculos para la comprobacin del Cif (Entidad jurdica) /// </summary> private bool CompruebaCif() { string[] letrasCodigo = { "J", "A", "B", "C", "D", "E", "F", "G", "H", "I" }; string n = Numero.ToString("0000000"); Int32 sumaPares = 0; Int32 sumaImpares = 0; Int32 sumaTotal = 0; Int32 i = 0; bool retVal = false; // Recorrido por todos los dgitos del nmero for (i = 0; i < n.Length; i++)

{ Int32 aux; Int32.TryParse(n[i].ToString(), out aux); if ((i + 1) % 2 == 0) { // Si es una posicin par, se suman los dgitos sumaPares += aux; } else { // Si es una posicin impar, se multiplican los dgitos por 2 aux = aux * 2; // se suman los dgitos de la suma sumaImpares += SumaDigitos(aux); } } // Se suman los resultados de los nmeros pares e impares sumaTotal += sumaPares + sumaImpares; // Se obtiene el dgito de las unidades Int32 unidades = sumaTotal % 10; // Si las unidades son distintas de 0, se restan de 10 if (unidades != 0) unidades = 10 - unidades; switch (LetraInicial) { // Slo nmeros case "A": case "B": case "E": case "H": retVal = DigitoControl == unidades.ToString(); break; // Slo letras case "K": case "P": case "Q": case "S": retVal = DigitoControl == letrasCodigo[unidades]; break; default:

retVal = (DigitoControl == unidades.ToString()) || (DigitoControl == letrasCodigo[unidades]); break; } return retVal; } /// <summary> /// Obtiene la suma de todos los dgitos /// </summary> /// <returns>de 23, devuelve la suma de 2 + 3</returns> private Int32 SumaDigitos(Int32 digitos) { string sNumero = digitos.ToString(); Int32 suma = 0; for (Int32 i = 0; i < sNumero.Length; i++) { Int32 aux; Int32.TryParse(sNumero[i].ToString(), out aux); suma += aux; } return suma; } /// <summary> /// Obtiene la letra correspondiente al Dni /// </summary> private string GetLetraNif() { int indice = Numero % 23; return "TRWAGMYFPDXBNJZSQVHLCKET"[indice].ToString(); } /// <summary> /// Obtiene una cadena con el nmero de identificacin completo /// </summary> public override string ToString() { string nif; string formato = "{0:0000000}"; if (tipo == TiposCodigosEnum.CIF && LetraInicial == "") formato = "{0:00000000}"; if (tipo == TiposCodigosEnum.NIF)

formato = "{0:00000000}"; nif = EsIntraComunitario ? CodigoIntracomunitario : string.Empty + LetraInicial + string.Format(formato,Numero ) + DigitoControl; return nif; } #endregion /// <summary> /// Comprobacin de un nmero de identificacin fiscal espaol /// </summary> /// <param name="numero">Numero a analizar</param> /// <returns>Instancia de <see cref="NumeroNif"/> con los datos del nmero. /// Destacable la propiedad <seealso cref="NumeroNif.EsCorrecto"/>, que contiene la verificacin /// </returns> public static NumeroNif CompruebaNif(string numero) { return new NumeroNif(numero); }

También podría gustarte