lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 0.9-5-ga4012f5

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

python-stdnum branch master updated. 0.9-5-ga4012f5



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  a4012f59d8afa3dcb3030809cb77705cb964cf28 (commit)
      from  71d9837302612de4b53c64e91a5c2a2b56192f30 (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 -----------------------------------------------------------------
http://arthurdejong.org/git/python-stdnum/commit/?id=a4012f59d8afa3dcb3030809cb77705cb964cf28

commit a4012f59d8afa3dcb3030809cb77705cb964cf28
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Mon Feb 17 22:40:18 2014 +0100

    Add support for 2013 extension of Irish PPS Numbers
    
    References:
    - https://www.welfare.ie/en/Pages/PPSN.aspx
    - 
http://www.citizensinformation.ie/en/social_welfare/irish_social_welfare_system/personal_public_service_number.html

diff --git a/stdnum/ie/pps.py b/stdnum/ie/pps.py
index 0447bf3..baa27e8 100644
--- a/stdnum/ie/pps.py
+++ b/stdnum/ie/pps.py
@@ -1,6 +1,7 @@
 # pps.py - functions for handling Irish PPS numbers
 #
 # Copyright (C) 2012, 2013 Arthur de Jong
+# Copyright (C) 2014 Olivier Dony
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -19,17 +20,32 @@
 
 """PPS No (Personal Public Service Number, Irish personal number).
 
-The Personal Public Service number consists of 8 digits. The first seven
-are numeric and the last is the check character. The number is sometimes
-be followed by an extra letter that can be a 'W', 'T' or an 'X' and is
-ignored for the check algorithm.
+The Personal Public Service number consists of 7 digits, and one or
+two letters. The first letter is a check character.
+When present (which should be the case for new numbers as of 2013),
+the second letter can be 'A' (for individuals) or 'H' (for
+non-individuals, such as limited companies, trusts, partnerships
+and unincorporated bodies). Pre-2013 values may have 'W', 'T',
+or 'X' as the second letter ; it is ignored by the check.
 
->>> validate('6433435F')
+>>> validate('6433435F')  # pre-2013
 '6433435F'
+>>> validate('6433435FT')  # pre-2013 with special final 'T'
+'6433435FT'
+>>> validate('6433435FW')  # pre-2013 format for married women
+'6433435FW'
 >>> validate('6433435E')  # incorrect check digit
 Traceback (most recent call last):
     ...
 InvalidChecksum: ...
+>>> validate('6433435OA')  # 2013 format (personal)
+'6433435OA'
+>>> validate('6433435IH')  # 2013 format (non-personal)
+'6433435IH'
+>>> validate('6433435VH')  # 2013 format (incorrect check)
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
 """
 
 import re
@@ -39,7 +55,7 @@ from stdnum.ie import vat
 from stdnum.util import clean
 
 
-pps_re = re.compile('^\d{7}[A-W][WTX]?$')
+pps_re = re.compile('^\d{7}[A-W][AHWTX]?$')
 """Regular expression used to check syntax of PPS numbers."""
 
 
@@ -55,8 +71,14 @@ def validate(number):
     number = compact(number)
     if not pps_re.match(number):
         raise InvalidFormat()
-    if number[7] != vat.calc_check_digit(number[:7]):
-        raise InvalidChecksum()
+    if len(number) == 9 and number[8] in 'AH':
+        # new 2013 format
+        if number[7] != vat.calc_check_digit(number[:7] + number[8:]):
+            raise InvalidChecksum()
+    else:
+        # old format, last letter ignored
+        if number[7] != vat.calc_check_digit(number[:7]):
+            raise InvalidChecksum()
     return number
 
 
diff --git a/stdnum/ie/vat.py b/stdnum/ie/vat.py
index 1988093..c3740e7 100644
--- a/stdnum/ie/vat.py
+++ b/stdnum/ie/vat.py
@@ -22,8 +22,10 @@
 The Irish VAT number consists of 8 digits. The last digit is a check
 letter, the second digit may be a number, a letter, "+" or "*".
 
->>> validate('IE 6433435F')
+>>> validate('IE 6433435F')  # pre-2013 format
 '6433435F'
+>>> validate('IE 6433435OA')  # 2013 format
+'6433435OA'
 >>> validate('6433435E')  # incorrect check digit
 Traceback (most recent call last):
     ...
@@ -53,8 +55,10 @@ def calc_check_digit(number):
     """Calculate the check digit. The number passed should not have the
     check digit included."""
     alphabet = 'WABCDEFGHIJKLMNOPQRSTUV'
-    number = (7 - len(number)) * '0' + number
-    return alphabet[sum((8 - i) * int(n) for i, n in enumerate(number)) % 23]
+    number = compact(number).zfill(7)
+    return alphabet[(
+        sum((8 - i) * int(n) for i, n in enumerate(number[:7])) +
+        9 * alphabet.index(number[7:])) % 23]
 
 
 def validate(number):
@@ -63,15 +67,15 @@ def validate(number):
     number = compact(number)
     if not number[:1].isdigit() or not number[2:7].isdigit():
         raise InvalidFormat()
-    if len(number) != 8:
+    if len(number) not in (8, 9):
         raise InvalidLength()
     if number[:7].isdigit():
         # new system
-        if number[-1] != calc_check_digit(number[:-1]):
+        if number[7] != calc_check_digit(number[:7] + number[8:]):
             raise InvalidChecksum()
     elif number[1] in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ+*':
         # old system
-        if number[-1] != calc_check_digit(number[2:-1] + number[0]):
+        if number[7] != calc_check_digit(number[2:7] + number[0]):
             raise InvalidChecksum()
     else:
         raise InvalidFormat()
diff --git a/tests/test_eu_vat.doctest b/tests/test_eu_vat.doctest
index b1c67a0..098dfd1 100644
--- a/tests/test_eu_vat.doctest
+++ b/tests/test_eu_vat.doctest
@@ -387,6 +387,8 @@ These have been found online and should all be valid 
numbers.
 ... IE6599001W
 ... IE8D79739I
 ... IE9Y71814N
+... IE6433435OA
+... IE6433435IH
 ...
 ... IT - 01404480202
 ... IT 0 0 6 1 8 2 8 0 4 9 9

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

Summary of changes:
 stdnum/ie/pps.py          |   38 ++++++++++++++++++++++++++++++--------
 stdnum/ie/vat.py          |   16 ++++++++++------
 tests/test_eu_vat.doctest |    2 ++
 3 files changed, 42 insertions(+), 14 deletions(-)


hooks/post-receive
-- 
python-stdnum
-- 
To unsubscribe send an email to
python-stdnum-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/python-stdnum-commits/