lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.12-7-g9605dbe

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.12-7-g9605dbe



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  9605dbed3accf05c5e698f0d5d4b38a63b57f1c7 (commit)
      from  087c668560148de86084b247c4dffafb19f5c3fe (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-stdnum/commit/?id=9605dbed3accf05c5e698f0d5d4b38a63b57f1c7

commit 9605dbed3accf05c5e698f0d5d4b38a63b57f1c7
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sat Jan 4 22:25:25 2020 +0100

    The Italian IVA is also a Codice Fiscale
    
    Closes https://github.com/arthurdejong/python-stdnum/issues/180

diff --git a/stdnum/it/codicefiscale.py b/stdnum/it/codicefiscale.py
index b1b9b1f..b38022c 100644
--- a/stdnum/it/codicefiscale.py
+++ b/stdnum/it/codicefiscale.py
@@ -7,7 +7,7 @@
 #
 # Copyright (C) 2009-2013 Emanuele Rocca
 # Copyright (C) 2014 Augusto Destrero
-# Copyright (C) 2014 Arthur de Jong
+# Copyright (C) 2014-2020 Arthur de Jong
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -26,18 +26,31 @@
 
 """Codice Fiscale (Italian tax code for individuals).
 
-The Codice Fiscale is an alphanumeric code of 16 characters used to
-identify individuals residing in Italy. The number consists of three
-characters derived from the person's last name, three from the person's
-first name, five that hold information on the person's gender and birth
-date, four that represent the person's place of birth and one check digit.
+The Codice Fiscale is an alphanumeric code of 16 characters used to identify
+individuals residing in Italy or 11 digits for non-individuals in which case
+it matches the Imposta sul valore aggiunto.
 
->>> validate('RCCMNL83S18D969H')
+The 16 digit number consists of three characters derived from the person's
+last name, three from the person's first name, five that hold information on
+the person's gender and birth date, four that represent the person's place of
+birth and one check digit.
+
+More information:
+
+* https://it.m.wikipedia.org/wiki/Codice_fiscale
+
+>>> validate('RCCMNL83S18D969H')  # personal number
 'RCCMNL83S18D969H'
 >>> validate('RCCMNL83S18D969')
 Traceback (most recent call last):
     ...
 InvalidLength: ...
+>>> validate('00743110157')  # company number
+'00743110157'
+>>> validate('00743110158')  # company number with invalid check digit
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
 >>> calc_check_digit('RCCMNL83S18D969')
 'H'
 """
@@ -46,10 +59,11 @@ import datetime
 import re
 
 from stdnum.exceptions import *
+from stdnum.it import iva
 from stdnum.util import clean
 
 
-# regular expression for matching fiscal codes
+# regular expression for matching personal fiscal codes
 _code_re = re.compile(
     r'^[A-Z]{6}'
     r'[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST]{1}[0-9LMNPQRSTUV]{2}'
@@ -80,12 +94,12 @@ del values
 def compact(number):
     """Convert the number to the minimal representation. This strips the
     number of any valid separators and removes surrounding whitespace."""
-    return clean(number, ' ').strip().upper()
+    return clean(number, ' -:').strip().upper()
 
 
 def calc_check_digit(number):
-    """Compute the control code for the given number. The passed number
-    should be the first 15 characters of a fiscal code."""
+    """Compute the control code for the given personal number. The passed
+    number should be the first 15 characters of a fiscal code."""
     code = sum(_odd_values[x] if n % 2 == 0 else _even_values[x]
                for n, x in enumerate(number))
     return 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[code % 26]
@@ -103,6 +117,8 @@ def get_birth_date(number, minyear=1920):
     datetime.date(2083, 11, 18)
     """
     number = compact(number)
+    if len(number) != 16:
+        raise InvalidComponent()
     day = (_date_digits[number[9]] * 10 + _date_digits[number[10]]) % 40
     month = _month_digits[number[8]] + 1
     year = _date_digits[number[6]] * 10 + _date_digits[number[7]]
@@ -125,6 +141,8 @@ def get_gender(number):
     'F'
     """
     number = compact(number)
+    if len(number) != 16:
+        raise InvalidComponent()
     return 'M' if int(number[9:11]) < 32 else 'F'
 
 
@@ -132,6 +150,8 @@ def validate(number):
     """Check if the given fiscal code is valid. This checks the length and
     whether the check digit is correct."""
     number = compact(number)
+    if len(number) == 11:
+        return iva.validate(number)
     if len(number) != 16:
         raise InvalidLength()
     if not _code_re.match(number):
diff --git a/tests/test_it_codicefiscale.doctest 
b/tests/test_it_codicefiscale.doctest
index 0dc033a..81b8b38 100644
--- a/tests/test_it_codicefiscale.doctest
+++ b/tests/test_it_codicefiscale.doctest
@@ -2,7 +2,7 @@ test_it_codicefiscale.doctest - tests for the 
stdnum.it.codicefiscale module
 
 Copyright (C) 2009-2013 Emanuele Rocca
 Copyright (C) 2014 Augusto Destrero
-Copyright (C) 2014 Arthur de Jong
+Copyright (C) 2014-2020 Arthur de Jong
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
@@ -89,6 +89,10 @@ datetime.date(1945, 3, 12)
 datetime.date(1945, 3, 12)
 >>> codicefiscale.get_birth_date('MRTNTN23M02D969P')
 datetime.date(1923, 8, 2)
+>>> codicefiscale.get_birth_date('00743110157')  # only for personal numbers
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
 
 
 Test getting the gender.
@@ -107,6 +111,10 @@ Test getting the gender.
 'M'
 >>> codicefiscale.get_gender('MAILCU91A25F839D')
 'M'
+>>> codicefiscale.get_gender('00743110157')  # only for personal numbers
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
 
 
 Test calculating the check digit.

-----------------------------------------------------------------------

Summary of changes:
 stdnum/it/codicefiscale.py          | 42 +++++++++++++++++++++++++++----------
 tests/test_it_codicefiscale.doctest | 10 ++++++++-
 2 files changed, 40 insertions(+), 12 deletions(-)


hooks/post-receive
-- 
python-stdnum