Add support for 2013 extension of Irish PPS Numbers · arthurdejong/python-stdnum@a4012f5
11# pps.py - functions for handling Irish PPS numbers
22#
33# Copyright (C) 2012, 2013 Arthur de Jong
4+# Copyright (C) 2014 Olivier Dony
45#
56# This library is free software; you can redistribute it and/or
67# modify it under the terms of the GNU Lesser General Public
@@ -19,17 +20,32 @@
19202021"""PPS No (Personal Public Service Number, Irish personal number).
212222-The Personal Public Service number consists of 8 digits. The first seven
23-are numeric and the last is the check character. The number is sometimes
24-be followed by an extra letter that can be a 'W', 'T' or an 'X' and is
25-ignored for the check algorithm.
23+The Personal Public Service number consists of 7 digits, and one or
24+two letters. The first letter is a check character.
25+When present (which should be the case for new numbers as of 2013),
26+the second letter can be 'A' (for individuals) or 'H' (for
27+non-individuals, such as limited companies, trusts, partnerships
28+and unincorporated bodies). Pre-2013 values may have 'W', 'T',
29+or 'X' as the second letter ; it is ignored by the check.
263027->>> validate('6433435F')
31+>>> validate('6433435F') # pre-2013
2832'6433435F'
33+>>> validate('6433435FT') # pre-2013 with special final 'T'
34+'6433435FT'
35+>>> validate('6433435FW') # pre-2013 format for married women
36+'6433435FW'
2937>>> validate('6433435E') # incorrect check digit
3038Traceback (most recent call last):
3139 ...
3240InvalidChecksum: ...
41+>>> validate('6433435OA') # 2013 format (personal)
42+'6433435OA'
43+>>> validate('6433435IH') # 2013 format (non-personal)
44+'6433435IH'
45+>>> validate('6433435VH') # 2013 format (incorrect check)
46+Traceback (most recent call last):
47+ ...
48+InvalidChecksum: ...
3349"""
34503551import re
@@ -39,7 +55,7 @@
3955from stdnum.util import clean
4056415742-pps_re = re.compile('^\d{7}[A-W][WTX]?$')
58+pps_re = re.compile('^\d{7}[A-W][AHWTX]?$')
4359"""Regular expression used to check syntax of PPS numbers."""
44604561@@ -55,8 +71,14 @@ def validate(number):
5571number = compact(number)
5672if not pps_re.match(number):
5773raise InvalidFormat()
58-if number[7] != vat.calc_check_digit(number[:7]):
59-raise InvalidChecksum()
74+if len(number) == 9 and number[8] in 'AH':
75+# new 2013 format
76+if number[7] != vat.calc_check_digit(number[:7] + number[8:]):
77+raise InvalidChecksum()
78+else:
79+# old format, last letter ignored
80+if number[7] != vat.calc_check_digit(number[:7]):
81+raise InvalidChecksum()
6082return number
61836284