Source code for localflavor.bg.validators

from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible
from django.utils.translation import gettext_lazy as _

from .utils import get_egn_birth_date


[docs]@deconstructible class EGNValidator: """ Check Bulgarian unique citizenship number (EGN) for validity. More details https://en.wikipedia.org/wiki/Unique_citizenship_number Full information in Bulgarian about algorithm is available here http://www.grao.bg/esgraon.html#section2 """ def _check_checksum(self, egn): weights = (2, 4, 8, 5, 10, 9, 7, 3, 6) try: checksum = sum(weight * int(digit) for weight, digit in zip(weights, egn)) return int(egn[-1]) == checksum % 11 % 10 except ValueError: return False def _check_valid_date(self, egn): try: return get_egn_birth_date(egn) except ValueError: return None def __call__(self, egn): if not (len(egn) == 10 and self._check_checksum(egn) and self._check_valid_date(egn)): raise ValidationError(_("The EGN is not valid"), code='invalid')
[docs]@deconstructible class EIKValidator: """ Check Bulgarian EIK/BULSTAT codes for validity. Full information in Bulgarian about algorithm is available here http://bulstat.registryagency.bg/About.html """ error_message = _('EIK/BULSTAT is not valid') def __call__(self, value): try: value = list(map(int, value)) except ValueError: raise ValidationError(self.error_message, code='invalid') if not (len(value) in [9, 13] and self._check_eik_base(value)): raise ValidationError(self.error_message, code='invalid') if len(value) == 13 and not self._check_eik_extra(value): raise ValidationError(self.error_message, code='invalid') def _get_checksum(self, weights, digits): checksum = sum(weight * digit for weight, digit in zip(weights, digits)) return checksum % 11 def _check_eik_base(self, eik): checksum = self._get_checksum(range(1, 9), eik) if checksum == 10: checksum = self._get_checksum(range(3, 11), eik) return eik[8] == checksum % 10 def _check_eik_extra(self, eik): digits = eik[8:12] checksum = self._get_checksum((2, 7, 3, 5), digits) if checksum == 10: checksum = self._get_checksum((4, 9, 5, 7), digits) return eik[-1] == checksum % 10
eik_validator = EIKValidator() egn_validator = EGNValidator()