Dinaup.Validations

ValidationUtils, Municipios y CodigosPostales comprueban NIF y VAT, consultan VIES y AEAT, clasifican el IVA y resuelven países, provincias y municipios del INE.

El módulo de validaciones del paquete Dinaup comprueba datos fiscales y geográficos antes de guardarlos: formato de NIF y VAT, alta en VIES y en la AEAT, territorialidad del IVA, códigos postales, provincias, municipios del INE y países. Los módulos ValidationUtils, Municipios y CodigosPostales están en el namespace Dinaup; las consultas a VIES y AEAT se hacen sobre un DinaupClientC conectado.

Antes de empezar

  • Paquete Dinaup instalado. Ver SDK .NET.
  • Para CheckVATViesAsync y CheckVATAEATAsync, un cliente conectado. Ver Cliente Dinaup.
using Dinaup;

Códigos postales y provincias

MétodoQué hace
ValidationUtils.IsSpanishPostalCode(postalCode)true si son cinco dígitos y los dos primeros corresponden a una provincia.
ValidationUtils.GetSpainProvinceFromPostalCode(postalCode)Nombre de la provincia del código postal, o cadena vacía.
CodigosPostales.GetMunicipiosByCP(cp)List<MunicipioData> con los municipios del INE que comparten ese código postal.
Console.WriteLine(ValidationUtils.IsSpanishPostalCode("03201")); // True
Console.WriteLine(ValidationUtils.IsSpanishPostalCode("99999")); // False
Console.WriteLine(ValidationUtils.GetSpainProvinceFromPostalCode("28013")); // Madrid

foreach (var m in CodigosPostales.GetMunicipiosByCP("03201"))
    Console.WriteLine($"{m.CodigoINE} {m.Nombre}");

Municipios del INE

El módulo Municipios embebe la relación oficial de municipios del INE y la expone con índices por código y por provincia. Cada MunicipioData trae CodigoProvincia (dos dígitos), CodigoMunicipio (tres), DigitoControl, Nombre tal como lo publica el INE, CodigoINE (cinco dígitos) y CodigoINEConDC (seis).

MétodoQué hace
Municipios.AllMunicipiosTodos los municipios.
Municipios.GetMunicipioByCodigoINE(codigoINE)Un municipio por su código de cinco dígitos, o null.
Municipios.GetMunicipio(nombre, codigoProvincia = null)Un municipio por nombre, sin distinguir mayúsculas ni acentos y con tolerancia a formas bilingües (Alicante encuentra Alicante/Alacant).
Municipios.SearchMunicipio(query, codigoProvincia = null)Municipios cuyo nombre contiene las palabras de query.
Municipios.GetMunicipiosByProvincia(codigoProvincia)Los municipios de una provincia ("03" para Alicante).
Municipios.IsValidMunicipio(nombre, codigoProvincia = null)true si el nombre es un municipio real, y de esa provincia si la indicas.
var elche = Municipios.GetMunicipio("Elche", "03");
Console.WriteLine(elche.CodigoINE);   // 03065

Nombres de localidad

ValidationUtils.NormalizeLocationName(name) convierte nombres en lenguas cooficiales al nombre en castellano (elx a Elche, Bilbo a Bilbao, Girona a Gerona). Si llega Alicante/Alacant, se queda con el primer tramo. Los nombres que no reconoce vuelven en minúsculas.

ValidationUtils.GetNormalizedAddressDataWithGoogleMaps(codigoPostal, pais, provincia, municipio, apiKey, language = "es") consulta la API de Google Maps y devuelve un NormalizedAddress con Country, CountryCode, Province, City y PostalCode.

Países

CountryData tiene ISO2, ENName, ESName y AllNames. ValidationUtils.AllCountryData es la lista completa y ValidationUtils.CountryEuCodes los códigos de la Unión Europea.

MétodoQué hace
ValidationUtils.SearchCountry(query)Coincidencias parciales por nombre en inglés o español, o por ISO2.
ValidationUtils.GetCountry(countryCodeOrNAme)Un país por ISO2 o nombre completo.
ValidationUtils.IsEuCountryCode(countryCode)true si el código ISO2 pertenece a la Unión Europea. Sin distinguir mayúsculas.
var spain = ValidationUtils.GetCountry("España");
Console.WriteLine($"{spain.ISO2} - {spain.ENName}");   // ES - Spain

Console.WriteLine(ValidationUtils.IsEuCountryCode("DE")); // True
Console.WriteLine(ValidationUtils.IsEuCountryCode("US")); // False

Reglas de región

ValidationUtils.IsLocationMatched(regionRule, isIncludeMode, inputCountryCode, inputProvinceCode, inputPostalCode) decide si una ubicación cumple una regla de regiones. regionRule es una lista separada por comas de patrones: ES (país), ES[Tenerife] (provincia, por nombre o por código postal), ES[Canarias] (códigos postales 35 y 38) y ES[!Tenerife] para negar una provincia. Con isIncludeMode en true solo pasan las ubicaciones que coinciden; en false, pasan todas salvo las que coinciden. Una regla vacía deja pasar todo y un país vacío no pasa nunca. La negación se evalúa antes y gana en los dos modos.

// Todo menos Canarias
bool enviable = ValidationUtils.IsLocationMatched("ES[!Canarias]", false, "ES", "Alicante", "03201");   // True
bool canarias = ValidationUtils.IsLocationMatched("ES[!Canarias]", false, "ES", "Las Palmas", "35001"); // False

// Solo España y Portugal
bool iberia = ValidationUtils.IsLocationMatched("ES,PT", true, "FR", "", "75001");   // False

NIF y VAT

MétodoQué hace
ValidationUtils.IsVIESVatFormat(vatNumber)true si tiene al menos cinco caracteres y empieza por el código de un país de la UE. Solo valida la estructura.
ValidationUtils.IsSpanishBusinessNIFFormat(taxID)true si el valor parece un NIF de empresa española: no empieza por un código de país de la UE, ni por dígito, ni por X, Y, Z, K, L o M. Filtro rápido; la validación real la hace la AEAT.
Console.WriteLine(ValidationUtils.IsVIESVatFormat("ES123456789")); // True
Console.WriteLine(ValidationUtils.IsVIESVatFormat("US123456789")); // False

Console.WriteLine(ValidationUtils.IsSpanishBusinessNIFFormat("B12345678")); // True
Console.WriteLine(ValidationUtils.IsSpanishBusinessNIFFormat("X1234567"));  // False

Consultar VIES y AEAT

Las dos consultas salen del servidor de Dinaup y se llaman sobre el cliente conectado.

  • CheckVATViesAsync(vatid) pregunta a VIES si el NIF está dado de alta como operador intracomunitario. Devuelve bool?: true alta confirmada, false no es operador (o formato inválido, o país no comunitario) y null si VIES no responde.

    bool? esIntracomunitario = await dinaupClient.CheckVATViesAsync("ESB12345678");
  • CheckVATAEATAsync(vatid, name) pregunta a la AEAT si el NIF y el nombre coinciden. Devuelve un CheckVATAEATResponse con Identificado, Nif, Nombre y Resultado. Identificado es true cuando Resultado vale IDENTIFICADO.

    var result = await dinaupClient.CheckVATAEATAsync("12345678Z", "Ana López Martín");
    Console.WriteLine(result.Identificado); // True solo si la AEAT identifica ese NIF con ese nombre

    Si la AEAT no contesta, no lanza excepción: devuelve Resultado vacío, que es "sin veredicto" y no un rechazo. Con un NIF vacío o de menos de 4 caracteres devuelve la respuesta vacía sin preguntar.

Territorialidad del IVA

ValidationUtils.ClassifyVatTerritoriality(nif, countryCode, postalCode, isVies) clasifica una operación por el lugar de tributación y devuelve un VatTerritoriality:

ValorCuándo
SimplifiedSin NIF: venta simplificada, típica de TPV.
ExportPaís fuera de la UE.
OutOfVatTerritoryEspaña con código postal de Canarias (35, 38), Ceuta (51) o Melilla (52).
NationalResto de España.
IntraCommunityOtro país de la UE con isVies en true.
OneStopShopOtro país de la UE sin VIES: régimen de ventanilla única.
UnknownReservado para datos insuficientes.
var tipo = ValidationUtils.ClassifyVatTerritoriality("B12345678", "ES", "03201", false);
Console.WriteLine(tipo); // National

var tipo2 = ValidationUtils.ClassifyVatTerritoriality("DE123456789", "DE", "81549", true);
Console.WriteLine(tipo2); // IntraCommunity

Para escribir el resultado en una venta, el campo de impuestos de la sección está en el Catálogo de secciones del núcleo.

En esta página