﻿ DNI functions | InterSystems Developer Community | Code Snippet|Tips &
Article
PILAR GUERRERO · Apr 25, 2018 4m read

# DNI functions

Hi everyone!

I want to share four functions with you. I hope that you can use it at some time.

DNI: the initials of the type of national identity document, is composed of different series of numbers and letters. That proves the identity and personal data of the holder, as well as the Spanish nationality. Example: 94494452X

NIE:  The NIE or foreigner identity number is a code for foreigners in Spain.

The first function calculates the letter of  a DNI number.

```/// Calculate letter of DNI
/// <br><b>pDni</b> format: con 8 numbers
ClassMethod GetLetterDni(pDni As %String) As %String
{
set correspondence = \$LISTBUILD("T","R","W","A","G","M","Y","F","P","D","X","B","N","J","Z","S","Q","V","H","L","C","K","E")

set letter = ""

if (pDni '= "") & (\$GET(pDni)?8N){
set num = (pDni # 23)+1
set letter = \$LISTGET(correspondence,num)
}

quit letter
}
```

The second function calculates a  letter of NIE using the first function.

```/// Calculate letter of NIE
/// <br><b>pNie</b> format: 1 letter, 7 numbers
ClassMethod GetLetterNie(pNie As %String) As %String
{
set letter = ""
//Get the first value
set letter1 = \$ZCONVERT(\$EXTRACT(pNie,1,1),"U")
//Cogemos el resto del Nie para su posterior uso
set num = \$EXTRACT(pNie,2,8)

if (pNie '= "") & (\$GET(pNie)?1U7N){

//If NIE starts with X, the X is replaced by the 0
if (letter1 = "X") { set dni = 0_num }

//If NIE starts with Y, the Y is replaced by the 1
elseif(letter1 = "Y") { set dni = 1_num }

//If NIE starts with Z, the Z is replaced by the 2
elseif (letter1 = "Z"){ set dni = 2_num }

//Calculates the letter
set letter = ..GetLetterDni(dni)
}

quit letter
}```

The third function validates a DNI using the first function.

```/// <br><b>pDni</b> format: 8 numbers, 1 letter
/// <br><b>0</b> Dni OK
/// <br><b>-1</b> Dni error
ClassMethod ValidateDni(pDni As %String) As %Integer
{
set response = -1

if (pDni '= "") & (\$GET(pDni)?8N1U){
//Get the numbers
set auxNum = \$EXTRACT(pDni,1,8)

//Get the letter
set auxLetter = \$EXTRACT(pDni,9,9)

//Calculates letter of dni
set calculatedLetter = ..GetLetterDni(auxNum)

//If both letters are the same the DNI is valid
if (auxLetter = calculatedLetter) { set response = 0 }
}

quit response
}
```

The last function validates a NIE using the second function.

```/// <br><b>pNie</b> NIE format: 1 letter, 7 numbers, 1 letter
/// <br><b>0</b> NIE OK
/// <br><b>-1</b> NIE error
ClassMethod ValidateNie(pNie As %String) As %Integer
{
set response = -1

if (pNie '= "") & (\$GET(pNie)?1U7N1U){
//Get the "numbers"
set auxNum = \$EXTRACT(pNie,1,8)

//Get the first letter
set auxLetter = \$EXTRACT(pNie,9,9)

set calculatedLetter = ..GetLetterNie(auxNum)

//Si ambas letras son iguales el DNI es valido
if (auxLetter = calculatedLetter) { set response = 0 }
}

quit response
}```

Any comments to improve will be welcome!!!

 Regards  ;)
3
0 652
Discussion (8)3

Pilar, could you please extend your post with a bit details about DNI, looks like it is used only in Spain.
And it would be better, to translate comments to English.

Hi, Pilar!

Thanks for the article! What is DNI?

Hi,

I tried to explain a bit that is the DNI  updating the post.

Thank you Pili !!

Yes, we only use DNI (our national identifier) in Spain but your method still being useful for a lot of DC users... I hope more and more :-D

I think that in GetLetter the condition should be if \$get(pDni)?8n to validate that pDni contain 8 exactly 8 digits

And in ValidateDni the condition should be if \$get(pDni)?8n1u to validate that pDni contains exactly 8 digits followd by an uppercase letter.

Also in ValidateDni instead of ##class(DKI.Common.Utils.Utilitades).GetLetter(auxNumber) you should do ..GetLetter(auxNumber) in this way when you put both methods in the same class the class name doesn't have to be DKI.Common.Utils.Utilitades

More about pattern matching can be found here:

https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...

http://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?...

Thanks!!

Instead of using \$LENGTH(pDni) '= 8  I can use  \$GET(pDni)?8N

\$GET(pDni)?8N in the GetLetter method where your input is 8 digits and the output is the corresponding letter.

In ValidateDni your input is 8 digits and one uppercase letter so there you should use \$GET(pDni)?8N1U

So now the code will be something like this:

```ClassMethod GetLetter(pDni As %String) As %String
{
set correspondence = \$LISTBUILD("T","R","W","A","G","M","Y","F","P","D","X","B","N","J","Z","S","Q","V","H","L","C","K","E")

set letter = ""

if (\$get(pDni)?8N){
set number = (pDni # 23)+1
set letter = \$LISTGET(correspondence,number)
}

quit letter
}```
```/// <br><b>0</b> Dni OK
/// <br><b>-1</b> Dni error

ClassMethod ValidateDni(pDni As %String) As %Integer
{

set response = -1

if (\$get(pDni)?8N1U){
//Get the numbers of Dni
set auxNumber = \$EXTRACT(pDni,1,8)

//Get the letter of Dni
set auxLetter = \$EXTRACT(pDni,9,9)

//Calculate the letter of the dni
set calculatedLetter = ..GetLetter(auxNumber)

if (auxLetter = calculatedLetter){
set response = 0
}
}

quit response
}```