1
|
|
|
""" |
2
|
|
|
byceps.blueprints.admin.orga_presence.forms |
3
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4
|
|
|
|
5
|
|
|
:Copyright: 2014-2024 Jochen Kupperschmidt |
6
|
|
|
:License: Revised BSD (see `LICENSE` file for details) |
7
|
|
|
""" |
8
|
|
|
|
9
|
1 |
|
from datetime import datetime |
10
|
|
|
|
11
|
1 |
|
from flask_babel import gettext, lazy_gettext, to_user_timezone, to_utc |
12
|
1 |
|
from wtforms import DateTimeLocalField |
13
|
1 |
|
from wtforms.validators import InputRequired |
14
|
|
|
|
15
|
1 |
|
from byceps.util.datetime.range import DateTimeRange |
16
|
1 |
|
from byceps.util.l10n import LocalizedForm |
17
|
|
|
|
18
|
|
|
|
19
|
1 |
|
DATE_TIME_LOCAL_FIELD_FORMAT = '%Y-%m-%dT%H:%M' |
20
|
|
|
|
21
|
|
|
|
22
|
1 |
|
def build_presence_create_form( |
23
|
|
|
valid_range_utc: DateTimeRange, |
24
|
|
|
default_starts_at_utc: datetime, |
25
|
|
|
default_ends_at_utc: datetime, |
26
|
|
|
): |
27
|
|
|
class CreateForm(LocalizedForm): |
28
|
|
|
starts_at = DateTimeLocalField( |
29
|
|
|
lazy_gettext('Start'), |
30
|
|
|
default=to_user_timezone(default_starts_at_utc).replace( |
31
|
|
|
tzinfo=None |
32
|
|
|
), |
33
|
|
|
validators=[InputRequired()], |
34
|
|
|
format=DATE_TIME_LOCAL_FIELD_FORMAT, |
35
|
|
|
) |
36
|
|
|
ends_at = DateTimeLocalField( |
37
|
|
|
lazy_gettext('End'), |
38
|
|
|
default=to_user_timezone(default_ends_at_utc).replace(tzinfo=None), |
39
|
|
|
validators=[InputRequired()], |
40
|
|
|
format=DATE_TIME_LOCAL_FIELD_FORMAT, |
41
|
|
|
) |
42
|
|
|
|
43
|
|
|
def validate(self) -> bool: |
44
|
|
|
if not super().validate(): |
45
|
|
|
return False |
46
|
|
|
|
47
|
|
|
valid = True |
48
|
|
|
|
49
|
|
|
starts_at = to_utc(self.starts_at.data) |
50
|
|
|
ends_at = to_utc(self.ends_at.data) |
51
|
|
|
|
52
|
|
|
def append_date_time_error(field): |
53
|
|
|
field.errors.append(gettext('Value must be in valid range.')) |
54
|
|
|
|
55
|
|
|
if not (valid_range_utc.start <= starts_at < valid_range_utc.end): |
56
|
|
|
append_date_time_error(self.starts_at) |
57
|
|
|
valid = False |
58
|
|
|
|
59
|
|
|
# As the presence end timestamp is exclusive, it may match |
60
|
|
|
# the date range's end, which is exclusive, too. |
61
|
|
|
if not (valid_range_utc.start <= ends_at <= valid_range_utc.end): |
62
|
|
|
append_date_time_error(self.ends_at) |
63
|
|
|
valid = False |
64
|
|
|
|
65
|
|
|
if starts_at >= ends_at: |
66
|
|
|
self.form_errors.append( |
67
|
|
|
gettext('Start value must be before end value.') |
68
|
|
|
) |
69
|
|
|
valid = False |
70
|
|
|
|
71
|
|
|
return valid |
72
|
|
|
|
73
|
|
|
return CreateForm |
74
|
|
|
|