Skip to content

Commit 293136b

Browse files
committed
Support Latvian personal codes issued after 2017
These numbers no longer embed a birth date in the format. Closes #486
1 parent a906a1e commit 293136b

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

stdnum/lv/pvn.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# pvn.py - functions for handling Latvian PVN (VAT) numbers
22
# coding: utf-8
33
#
4-
# Copyright (C) 2012-2019 Arthur de Jong
4+
# Copyright (C) 2012-2026 Arthur de Jong
55
#
66
# This library is free software; you can redistribute it and/or
77
# modify it under the terms of the GNU Lesser General Public
@@ -23,20 +23,31 @@
2323
The PVN is a 11-digit number that can either be a reference to a legal
2424
entity (in which case the first digit > 3) or a natural person (in which
2525
case it should be the same as the personal code (personas kods)). Personal
26-
codes start with 6 digits to denote the birth date in the form ddmmyy.
26+
codes start "32". Older personal codes start with 6 digits to denote the birth
27+
date in the form ddmmyy.
28+
29+
More information:
30+
31+
* https://en.wikipedia.org/wiki/National_identification_number#Latvia
2732
2833
>>> validate('LV 4000 3521 600')
2934
'40003521600'
3035
>>> validate('40003521601') # invalid check digit
3136
Traceback (most recent call last):
3237
...
3338
InvalidChecksum: ...
34-
>>> validate('161175-19997') # personal code
39+
>>> validate('161175-19997') # personal code, old format
3540
'16117519997'
3641
>>> validate('161375-19997') # invalid date
3742
Traceback (most recent call last):
3843
...
3944
InvalidComponent: ...
45+
>>> validate('328673-00679') # personal code, new format
46+
'32867300679'
47+
>>> validate('328673-00677') # personal code, new format
48+
Traceback (most recent call last):
49+
...
50+
InvalidChecksum: ...
4051
"""
4152

4253
from __future__ import annotations
@@ -101,6 +112,10 @@ def validate(number: str) -> str:
101112
# legal entity
102113
if checksum(number) != 3:
103114
raise InvalidChecksum()
115+
elif number.startswith('32'):
116+
# personal code without a date of birth (issued from July 2017 onwards)
117+
if calc_check_digit_pers(number[:-1]) != number[-1]:
118+
raise InvalidChecksum()
104119
else:
105120
# natural resident, check if birth date is valid
106121
get_birth_date(number)

0 commit comments

Comments
 (0)