1
1
# pps.py - functions for handling Irish PPS numbers
2
2
#
3
3
# Copyright (C) 2012, 2013 Arthur de Jong
4
+ # Copyright (C) 2014 Olivier Dony
4
5
#
5
6
# This library is free software; you can redistribute it and/or
6
7
# modify it under the terms of the GNU Lesser General Public
19
20
20
21
"""PPS No (Personal Public Service Number, Irish personal number).
21
22
22
- 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.
26
30
27
- >>> validate('6433435F')
31
+ >>> validate('6433435F') # pre-2013
28
32
'6433435F'
33
+ >>> validate('6433435FT') # pre-2013 with special final 'T'
34
+ '6433435FT'
35
+ >>> validate('6433435FW') # pre-2013 format for married women
36
+ '6433435FW'
29
37
>>> validate('6433435E') # incorrect check digit
30
38
Traceback (most recent call last):
31
39
...
32
40
InvalidChecksum: ...
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: ...
33
49
"""
34
50
35
51
import re
39
55
from stdnum .util import clean
40
56
41
57
42
- pps_re = re .compile ('^\d{7}[A-W][WTX ]?$' )
58
+ pps_re = re .compile ('^\d{7}[A-W][AHWTX ]?$' )
43
59
"""Regular expression used to check syntax of PPS numbers."""
44
60
45
61
@@ -55,8 +71,14 @@ def validate(number):
55
71
number = compact (number )
56
72
if not pps_re .match (number ):
57
73
raise 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 ()
60
82
return number
61
83
62
84
0 commit comments