Skip to content

Commit c6e65ac

Browse files
committed
Fix decoding for people over 100 years old. #203
1 parent 8e14026 commit c6e65ac

2 files changed

Lines changed: 72 additions & 14 deletions

File tree

src/codicefiscale/codicefiscale.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -474,21 +474,35 @@ def decode(code: str) -> dict[str, Any]:
474474
birthdate_year = int(f"{current_year_century_prefix}{birthdate_year_suffix}")
475475
if birthdate_year > current_year:
476476
birthdate_year -= 100
477-
birthdate_str = f"{birthdate_year}/{birthdate_month}/{birthdate_day}"
478-
birthdate = _get_date(birthdate_str, separator="/")
479-
if not birthdate:
480-
raise ValueError(f"[codicefiscale] invalid date: {birthdate_str}")
481477

482-
birthplace_code = raw["birthplace"][0] + raw["birthplace"][1:].translate(
483-
_OMOCODIA_DECODE_TRANS
484-
)
485-
birthplace = _get_birthplace(birthplace_code, birthdate)
486-
# print(birthplace)
487-
if not birthplace:
488-
raise ValueError(
489-
"[codicefiscale] wrong birthplace code: "
490-
f"{birthplace_code!r} / birthdate: {birthdate.isoformat()!r}."
491-
)
478+
birthdate_or_birthplace_error = None
479+
for _ in range(2):
480+
birthdate_str = f"{birthdate_year}/{birthdate_month}/{birthdate_day}"
481+
try:
482+
birthdate = _get_date(birthdate_str, separator="/")
483+
if not birthdate:
484+
raise ValueError(f"[codicefiscale] invalid date: {birthdate_str}")
485+
486+
birthplace_code = raw["birthplace"][0] + raw["birthplace"][1:].translate(
487+
_OMOCODIA_DECODE_TRANS
488+
)
489+
birthplace = _get_birthplace(birthplace_code, birthdate)
490+
# print(birthplace)
491+
if not birthplace:
492+
raise ValueError(
493+
"[codicefiscale] wrong birthplace code: "
494+
f"{birthplace_code!r} / birthdate: {birthdate.isoformat()!r}."
495+
)
496+
break
497+
except ValueError as error:
498+
# attempt to handle people over 100 years old
499+
if birthdate_or_birthplace_error is None:
500+
birthdate_or_birthplace_error = error
501+
birthdate_year -= 100
502+
else:
503+
# raise the first raised error
504+
if birthdate_or_birthplace_error:
505+
raise birthdate_or_birthplace_error
492506

493507
cin = raw["cin"]
494508
cin_check = encode_cin(code)

tests/issues/test_issue_0203.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import datetime
2+
3+
from codicefiscale import codicefiscale
4+
5+
6+
def test_issue_0203():
7+
"""
8+
Test for people over 100 years old.
9+
https://github.com/fabiocaccamo/python-codicefiscale/issues/203
10+
"""
11+
code = codicefiscale.encode("Michele", "Faedi", "m", "01/01/1907", "Gallico")
12+
assert code == "MCHFDA07A01D877A"
13+
14+
code_data = codicefiscale.decode(code)
15+
code_data.pop("omocodes", None)
16+
expected_code_data = {
17+
"code": "MCHFDA07A01D877A",
18+
"gender": "M",
19+
"birthdate": datetime.datetime(1907, 1, 1, 0, 0),
20+
"birthplace": {
21+
"active": False,
22+
"code": "D877",
23+
"date_created": "1861-03-17T00:00:00",
24+
"date_deleted": "1927-08-02T00:00:00",
25+
"name": "Gallico",
26+
"name_alt": "",
27+
"name_alt_trans": "",
28+
"name_slugs": ["gallico"],
29+
"name_trans": "Gallico",
30+
"province": "RC",
31+
},
32+
"raw": {
33+
"code": "MCHFDA07A01D877A",
34+
"lastname": "MCH",
35+
"firstname": "FDA",
36+
"birthdate": "07A01",
37+
"birthdate_year": "07",
38+
"birthdate_month": "A",
39+
"birthdate_day": "01",
40+
"birthplace": "D877",
41+
"cin": "A",
42+
},
43+
}
44+
assert code_data == expected_code_data

0 commit comments

Comments
 (0)