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

3038

Traceback (most recent call last):

3139

...

3240

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: ...

3349

"""

34503551

import re

@@ -39,7 +55,7 @@

3955

from 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):

5571

number = compact(number)

5672

if not pps_re.match(number):

5773

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()

6082

return number

61836284