Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions alinka/schemas/document_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pydantic import BaseModel, Field, computed_field, model_validator

from alinka.constants import ActivityForm, Issue, Reason
from alinka.utils import extract_date_of_birth_from_pesel


class AddressData(BaseModel):
Expand Down Expand Up @@ -46,10 +47,7 @@ def calculate_date_of_birth(self) -> "ChildData":
if self.birth_date:
return self
pesel = self.pesel
year_part, month_part, day = int(pesel[0:2]), int(pesel[2:4]), int(pesel[4:6])
year = 2000 + year_part if month_part > 20 else 1900 + year_part
month = month_part - 20 if month_part > 20 else month_part
self.birth_date = date(year, month, day)
self.birth_date = extract_date_of_birth_from_pesel(pesel)
return self


Expand Down
32 changes: 32 additions & 0 deletions alinka/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from datetime import date


def extract_date_of_birth_from_pesel(pesel: str) -> date:
year_part, month_part, day = int(pesel[0:2]), int(pesel[2:4]), int(pesel[4:6])
year = 2000 + year_part if month_part > 20 else 1900 + year_part
month = month_part - 20 if month_part > 20 else month_part
return date(year, month, day)


def is_valid_pesel(pesel: str) -> bool:
if len(pesel) != 11 or not pesel.isdigit():
return False
weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]
digits = [int(ch) for ch in pesel]
checksum = (10 - sum(w * d for w, d in zip(weights, digits)) % 10) % 10
if checksum != digits[-1]:
return False
year_part, month_part, day = int(pesel[0:2]), int(pesel[2:4]), int(pesel[4:6])
if 1 <= month_part <= 12:
month = month_part
year = 1900 + year_part
elif 21 <= month_part <= 32:
month = month_part - 20
year = 2000 + year_part
else:
return False

try:
return bool(date(year, month, day))
except ValueError:
return False
10 changes: 3 additions & 7 deletions alinka/widget/validators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from PySide6.QtGui import QValidator

from alinka.utils import is_valid_pesel


class RequiredValidator(QValidator):
default_error_message = "To pole jest wymagane"
Expand All @@ -20,15 +22,9 @@ def validate(self, input_str: str, pos: int) -> tuple[QValidator.State, str, int
return QValidator.Invalid, input_str, pos
if len(input_str) > 12:
return QValidator.Invalid, input_str, pos

if len(input_str) < 11:
return QValidator.Intermediate, input_str, pos

weights = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3]
digits = [int(ch) for ch in input_str]
checksum = (10 - sum(w * d for w, d in zip(weights, digits)) % 10) % 10

if checksum == digits[-1]:
if is_valid_pesel(input_str):
return QValidator.Acceptable, input_str, pos
else:
return QValidator.Intermediate, input_str, pos
51 changes: 51 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from datetime import date

import pytest

from alinka.utils import extract_date_of_birth_from_pesel, is_valid_pesel


class TestValidatePesel:
@pytest.mark.parametrize(
"pesel",
[
"44051401359",
"07290423766",
"02070803628",
],
)
def test_validate_pesel__valid_pesel(self, pesel):
assert is_valid_pesel(pesel)

@pytest.mark.parametrize(
"pesel",
[
"44051401358", # Invalid checksum
"1234567890", # Too short
"83010412345",
"99022912345",
"88888888888", # Invalid date
"abcdefghijk", # Non-digit characters
"123456789012", # Too long
"", # Empty string
],
)
def test_validate_pesel__invalid_pesel(self, pesel):
assert not is_valid_pesel(pesel)


class TestPeselToDateOfBirth:
@pytest.mark.parametrize(
"pesel, expected_date",
[
("40301362951", date(2040, 10, 13)),
("39251058614", date(2039, 5, 10)),
("14230216474", date(2014, 3, 2)),
("39280845434", date(2039, 8, 8)),
("09321992876", date(2009, 12, 19)),
("05212294647", date(2005, 1, 22)),
],
)
def test_extract_date_of_birth_from_pesel__success(self, pesel, expected_date):
assert is_valid_pesel(pesel)
assert extract_date_of_birth_from_pesel(pesel) == expected_date