build_presence_create_form()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 52
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 26.8773

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 52
ccs 1
cts 23
cp 0.0434
rs 8.5493
c 0
b 0
f 0
cc 5
nop 3
crap 26.8773

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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