Skip to content
Open
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
8 changes: 1 addition & 7 deletions src/validators/i18n/ru.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,7 @@ def ru_inn(value: str):
control_number1 = sum([d * w for d, w in zip(digits, weight_coefs1)]) % 11
weight_coefs2 = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0]
control_number2 = sum([d * w for d, w in zip(digits, weight_coefs2)]) % 11
return (
(control_number1 % 10) == digits[-2]
if control_number1 > 9
else control_number1 == digits[-2] and (control_number2 % 10) == digits[-1]
if control_number2 > 9
else control_number2 == digits[-1]
)
return (control_number1 % 10) == digits[-2] and (control_number2 % 10) == digits[-1]
else:
return False
except ValueError:
Expand Down
19 changes: 19 additions & 0 deletions tests/i18n/test_ru.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,22 @@ def test_returns_true_on_valid_ru_inn(value: str):
def test_returns_false_on_valid_ru_inn(value: str):
"""Test returns true on valid russian individual tax number."""
assert isinstance(ru_inn(value), ValidationError)


@pytest.mark.parametrize(
"value",
[
"500100732266", # First check digit is wrong; the second matches.
"100000001103", # First remainder is 10; the second check digit is wrong.
"100000000781", # Second remainder is 10; its check digit must be zero.
],
)
def test_individual_inn_requires_both_check_digits(value: str):
"""Reject an individual INN when either check digit is wrong."""
assert isinstance(ru_inn(value), ValidationError)


@pytest.mark.parametrize("value", ["500100732259", "100000001102", "100000000780"])
def test_individual_inn_check_digit_remainders(value: str):
"""Accept both ordinary remainders and remainder 10 mapped to zero."""
assert ru_inn(value) is True