1 from __future__
import absolute_import
5 from django
.core
.validators
import EMPTY_VALUES
6 from django
.forms
import ValidationError
7 from django
.forms
.fields
import RegexField
, Select
8 from django
.utils
.translation
import ugettext_lazy
as _
10 from django
.contrib
.localflavor
.mk
.mk_choices
import MK_MUNICIPALITIES
13 class MKIdentityCardNumberField(RegexField
):
15 A Macedonian ID card number. Accepts both old and new format.
17 default_error_messages
= {
18 'invalid': _(u
'Identity card numbers must contain'
19 ' either 4 to 7 digits or an uppercase letter and 7 digits.'),
22 def __init__(self
, *args
, **kwargs
):
23 kwargs
['min_length'] = None
24 kwargs
['max_length'] = 8
25 regex
= ur
'(^[A-Z]{1}\d{7}$)|(^\d{4,7}$)'
26 super(MKIdentityCardNumberField
, self
).__init
__(regex
, *args
, **kwargs
)
29 class MKMunicipalitySelect(Select
):
31 A form ``Select`` widget that uses a list of Macedonian municipalities as
32 choices. The label is the name of the municipality and the value
33 is a 2 character code for the municipality.
36 def __init__(self
, attrs
=None):
37 super(MKMunicipalitySelect
, self
).__init
__(attrs
, choices
= MK_MUNICIPALITIES
)
40 class UMCNField(RegexField
):
42 A form field that validates input as a unique master citizen
45 The format of the unique master citizen number has been kept the same from
46 Yugoslavia. It is still in use in other countries as well, it is not applicable
47 solely in Macedonia. For more information see:
48 https://secure.wikimedia.org/wikipedia/en/wiki/Unique_Master_Citizen_Number
50 A value will pass validation if it complies to the following rules:
52 * Consists of exactly 13 digits
53 * The first 7 digits represent a valid past date in the format DDMMYYY
54 * The last digit of the UMCN passes a checksum test
56 default_error_messages
= {
57 'invalid': _(u
'This field should contain exactly 13 digits.'),
58 'date': _(u
'The first 7 digits of the UMCN must represent a valid past date.'),
59 'checksum': _(u
'The UMCN is not valid.'),
62 def __init__(self
, *args
, **kwargs
):
63 kwargs
['min_length'] = None
64 kwargs
['max_length'] = 13
65 super(UMCNField
, self
).__init
__(r
'^\d{13}$', *args
, **kwargs
)
67 def clean(self
, value
):
68 value
= super(UMCNField
, self
).clean(value
)
70 if value
in EMPTY_VALUES
:
73 if not self
._validate
_date
_part
(value
):
74 raise ValidationError(self
.error_messages
['date'])
75 if self
._validate
_checksum
(value
):
78 raise ValidationError(self
.error_messages
['checksum'])
80 def _validate_checksum(self
, value
):
81 a
,b
,c
,d
,e
,f
,g
,h
,i
,j
,k
,l
,K
= [int(digit
) for digit
in value
]
82 m
= 11 - (( 7*(a
+g
) + 6*(b
+h
) + 5*(c
+i
) + 4*(d
+j
) + 3*(e
+k
) + 2*(f
+l
)) % 11)
83 if (m
>= 1 and m
<= 9) and K
== m
:
85 elif m
== 11 and K
== 0:
90 def _validate_date_part(self
, value
):
91 daypart
, monthpart
, yearpart
= int(value
[:2]), int(value
[2:4]), int(value
[4:7])
97 date
= datetime
.datetime(year
= yearpart
, month
= monthpart
, day
= daypart
).date()
100 if date
>= datetime
.datetime
.now().date():