Author: Christian Cristofori
In Italy companies have a code for use with fiscal transactions. There's a checksum
digit.
This function not only checks for its validity, but also retrieves some interesting
information
from the code: the progressive number a company has in his state (provincia) and
the country
that generated that code.
Answer:
1 const
2 Provincie: array[0..102] of string =
3 ('Torino', 'Vercelli', 'Novara', 'Cuneo', 'Asti',
4 'Alessandria', 'Aosta', 'Imperia', 'Savona', 'Genova',
5 'La Spezia', 'Varese', 'Como', 'Sondrio', 'Milano',
6 'Bergamo', 'Brescia', 'Pavia', 'Cremona', 'Mantova',
7 'Bolzano-Bozen', 'Trento', 'Verona', 'Vicenza', 'Belluno',
8 'Treviso', 'Venezia', 'Padova', 'Rovigo', 'Udine',
9 'Gorizia', 'Trieste', 'Piacenza', 'Parma', 'Reggio nell''Emilia',
10 'Modena', 'Bologna', 'Ferrara', 'Ravenna', 'Forli''-Cesena',
11 'Pesaro e Urbino', 'Ancona', 'Macerata', 'Ascoli Piceno', 'Massa-Carrara',
12 'Lucca', 'Pistoia', 'Firenze', 'Livorno', 'Pisa',
13 'Arezzo', 'Siena', 'Grosseto', 'Perugia', 'Terni',
14 'Viterbo', 'Rieti', 'Roma', 'Latina', 'Frosinone',
15 'Caserta', 'Benevento', 'Napoli', 'Avellino', 'Salerno',
16 'L''Aquila', 'Teramo', 'Pescara', 'Chieti', 'Campobasso',
17 'Foggia', 'Bari', 'Taranto', 'Brindisi', 'Lecce',
18 'Potenza', 'Matera', 'Cosenza', 'Catanzaro', 'Reggio di Calabria',
19 'Trapani', 'Palermo', 'Messina', 'Agrigento', 'Caltanissetta',
20 'Enna', 'Catania', 'Ragusa', 'Siracusa', 'Sassari',
21 'Nuoro', 'Cagliari', 'Pordenone', 'Isernia', 'Oristano',
22 'Biella', 'Lecco', 'Lodi', 'Rimini', 'Prato',
23 'Crotone', 'Vibo Valentia', 'Verbano-Cusio-Ossola'
24 );
25
26 function PartitaIVA(code: string; var Progressive: integer; var Provincia: string):
27 boolean;
28 function ReduceSum(n: Integer): Integer;
29 var
30 i: Integer;
31 s: string;
32 begin
33 s := inttostr(n);
34 if (length(s) = 1) then
35 begin
36 result := n;
37 exit;
38 end;
39 result := 0;
40 for i := 1 to length(s) do
41 begin
42 result := result + strtointdef(s[i], 0);
43 end;
44 end;
45 function ReduceNum(n: Integer): Integer;
46 var
47 s: string;
48 begin
49 result := n;
50 s := inttostr(n);
51 if (length(s) > 1) then
52 begin
53 result := strtointdef(s[length(s)], 0)
54 end;
55 end;
56 var
57 i: Integer;
58 c: Integer;
59 begin
60 result := false;
61 if (length(code) <> 11) then
62 begin
63 provincia := '11 numeric-characters needed!';
64 raise exception.Create(provincia);
65 exit;
66 end;
67 for i := 1 to 11 do
68 begin
69 if (not (code[i] in ['0'..'9'])) then
70 begin
71 provincia := '"' + code[i] + '" is not a numeric value!';
72 raise exception.Create(provincia);
73 exit;
74 end;
75 end;
76 // Returns the town.
77 i := strtointdef(copy(code, 8, 3), 0) - 1;
78 if ((i < 0) or (i > 102)) then
79 begin
80 provincia := 'Value out of set!';
81 raise exception.create(provincia);
82 exit;
83 end
84 else
85 provincia := provincie[i];
86 // Returns the progressive number.
87 progressive := strtointdef(copy(code, 1, 7), 0);
88 // Calculates if is valid.
89 c := 0;
90 for i := 1 to 10 do
91 begin
92 if ((i mod 2) = 0) then
93 inc(c, reducesum(strtointdef(code[i], 0) * 2))
94 else
95 inc(c, strtointdef(code[i], 0));
96 end;
97 result := ((10 - ReduceNum(c)) = strtointdef(code[11], -1));
98 end;
|