2008. november 13., csütörtök

How to check italian code for companies


Problem/Question/Abstract:

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:

const
  Provincie: array[0..102] of string =
  ('Torino', 'Vercelli', 'Novara', 'Cuneo', 'Asti',
    'Alessandria', 'Aosta', 'Imperia', 'Savona', 'Genova',
    'La Spezia', 'Varese', 'Como', 'Sondrio', 'Milano',
    'Bergamo', 'Brescia', 'Pavia', 'Cremona', 'Mantova',
    'Bolzano-Bozen', 'Trento', 'Verona', 'Vicenza', 'Belluno',
    'Treviso', 'Venezia', 'Padova', 'Rovigo', 'Udine',
    'Gorizia', 'Trieste', 'Piacenza', 'Parma', 'Reggio nell''Emilia',
    'Modena', 'Bologna', 'Ferrara', 'Ravenna', 'Forli''-Cesena',
    'Pesaro e Urbino', 'Ancona', 'Macerata', 'Ascoli Piceno', 'Massa-Carrara',
    'Lucca', 'Pistoia', 'Firenze', 'Livorno', 'Pisa',
    'Arezzo', 'Siena', 'Grosseto', 'Perugia', 'Terni',
    'Viterbo', 'Rieti', 'Roma', 'Latina', 'Frosinone',
    'Caserta', 'Benevento', 'Napoli', 'Avellino', 'Salerno',
    'L''Aquila', 'Teramo', 'Pescara', 'Chieti', 'Campobasso',
    'Foggia', 'Bari', 'Taranto', 'Brindisi', 'Lecce',
    'Potenza', 'Matera', 'Cosenza', 'Catanzaro', 'Reggio di Calabria',
    'Trapani', 'Palermo', 'Messina', 'Agrigento', 'Caltanissetta',
    'Enna', 'Catania', 'Ragusa', 'Siracusa', 'Sassari',
    'Nuoro', 'Cagliari', 'Pordenone', 'Isernia', 'Oristano',
    'Biella', 'Lecco', 'Lodi', 'Rimini', 'Prato',
    'Crotone', 'Vibo Valentia', 'Verbano-Cusio-Ossola'
    );

function PartitaIVA(code: string; var Progressive: integer; var Provincia: string):
  boolean;
  function ReduceSum(n: Integer): Integer;
  var
    i: Integer;
    s: string;
  begin
    s := inttostr(n);
    if (length(s) = 1) then
    begin
      result := n;
      exit;
    end;
    result := 0;
    for i := 1 to length(s) do
    begin
      result := result + strtointdef(s[i], 0);
    end;
  end;
  function ReduceNum(n: Integer): Integer;
  var
    s: string;
  begin
    result := n;
    s := inttostr(n);
    if (length(s) > 1) then
    begin
      result := strtointdef(s[length(s)], 0)
    end;
  end;
var
  i: Integer;
  c: Integer;
begin
  result := false;
  if (length(code) <> 11) then
  begin
    provincia := '11 numeric-characters needed!';
    raise exception.Create(provincia);
    exit;
  end;
  for i := 1 to 11 do
  begin
    if (not (code[i] in ['0'..'9'])) then
    begin
      provincia := '"' + code[i] + '" is not a numeric value!';
      raise exception.Create(provincia);
      exit;
    end;
  end;
  // Returns the town.
  i := strtointdef(copy(code, 8, 3), 0) - 1;
  if ((i < 0) or (i > 102)) then
  begin
    provincia := 'Value out of set!';
    raise exception.create(provincia);
    exit;
  end
  else
    provincia := provincie[i];
  // Returns the progressive number.
  progressive := strtointdef(copy(code, 1, 7), 0);
  // Calculates if is valid.
  c := 0;
  for i := 1 to 10 do
  begin
    if ((i mod 2) = 0) then
      inc(c, reducesum(strtointdef(code[i], 0) * 2))
    else
      inc(c, strtointdef(code[i], 0));
  end;
  result := ((10 - ReduceNum(c)) = strtointdef(code[11], -1));
end;

Nincsenek megjegyzések:

Megjegyzés küldése