org.forms.allocation

Classes

DateContainer

Base class for protocol classes.

BatchCopyAllocationRulesForm

Extends wtforms.Form with useful methods and integrations needed in

AllocationFormHelpers

AllocationRuleForm

Base form form allocation rules.

AllocationForm

Baseform for all allocation forms. Allocation forms are expected

AllocationEditForm

Baseform for edit forms. Edit forms differ from the base allocation

Daypasses

DaypassAllocationForm

Baseform for all allocation forms. Allocation forms are expected

DaypassAllocationEditForm

Baseform for edit forms. Edit forms differ from the base allocation

RoomAllocationForm

Baseform for all allocation forms. Allocation forms are expected

DailyItemFields

DailyItemAllocationForm

Baseform for all allocation forms. Allocation forms are expected

DailyItemAllocationEditForm

Baseform for edit forms. Edit forms differ from the base allocation

RoomAllocationEditForm

Baseform for edit forms. Edit forms differ from the base allocation

Functions

choices_as_integer(→ list[int] | None)

Module Contents

class org.forms.allocation.DateContainer[source]

Bases: Protocol

Base class for protocol classes.

Protocol classes are defined as:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).

For example:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:

class GenProto[T](Protocol):
    def meth(self) -> T:
        ...
__contains__(dt: datetime.date | datetime.datetime, /) bool[source]
org.forms.allocation.choices_as_integer(choices: collections.abc.Iterable[str] | None) list[int] | None[source]
class org.forms.allocation.BatchCopyAllocationRulesForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: onegov.form.Form

Extends wtforms.Form with useful methods and integrations needed in OneGov applications.

Fieldsets

This form supports fieldsets (which WTForms doesn’t recognize). To put fields into a fieldset, add a fieldset attribute to the field during class definition:

class MyForm(Form):
    first_name = StringField('First Name', fieldset='Name')
    last_name = StringField('Last Name', fieldset='Name')
    comment = StringField('Comment')

A form created like this will have two fieldsets, one visible fieldset with the legend set to ‘Name’ and one invisible fieldset containing ‘comment’.

Fieldsets with the same name are not automatically grouped together. Instead, fields are taken in the order they are defined and put into the same fieldset, if the previous fieldset has the same name.

That is to say, in this example, we get three fieldsets:

class MyForm(Form):
    a = StringField('A', fieldset='1')
    b = StringField('B', fieldset='2')
    c = StringField('C', fieldset='1')

The first fieldset has the label ‘1’ and it contains ‘a’. The second fieldset has the label ‘2’ and it contains ‘b’. The third fieldset has the label ‘3’ and it contains ‘c’.

This ensures that all fields are in either a visible or an invisible fieldset (see Fieldset.is_visible()).

Dependencies

This form also supports dependencies. So field b may depend on field a, if field a has a certain value, field b is shown on the form (with some javascript) and its validators are actually executed. If field a does not have the required value, field b is hidden with javascript and its validators are not executed.

The validators which are skipped are only the validators passed with the field, the validators on the field itself are still invoked (we can’t skip them). However, only if the optional field is not empty. That is we prevent invalid values no matter what, but we allow for empty values if the dependent field does not have the required value.

This sounds a lot more complicated than it is:

class MyForm(Form):

    option = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No'),
    ])
    only_if_no = StringField(
        label='Only Shown When No',
        validators=[InputRequired()],
        depends_on=('option', 'no')
    )

Pricing

Pricing is a way to attach prices to certain form fields. A total price is calcualted depending on the selections the user makes:

class MyForm(Form):

    ticket_insurance = RadioField('Option', choices=[
        ('yes', 'Yes'),
        ('no', 'No')
    ], pricing={
        'yes': (10.0, 'CHF')
    })

    stamps = IntegerRangeField(
    'No. Stamps',
    range=range(0, 30),
    pricing={range(0, 30): (1.00, 'CHF')}
)

    delivery = RadioField('Delivery', choices=[
        ('pick_up', 'Pick up'),
        ('post', 'Post')
    ], pricing={
        'post': (5.0, 'CHF', True)
    })

    discount_code = StringField('Discount Code', pricing={
        'CAMPAIGN2017': (-5.0, 'CHF')
    })

Note that the pricing has no implicit meaning. This is simply a way to attach prices and to get the total through the prices() and total() calls. What you do with these prices is up to you.

Pricing can optionally take a third boolean value indicating that this option will make credit card payments mandatory.

model: onegov.reservation.Resource[source]
rules[source]
resources[source]
on_request() None[source]
class org.forms.allocation.AllocationFormHelpers[source]
generate_dates(start: datetime.date | None, end: datetime.date | None, start_time: datetime.time | None = None, end_time: datetime.time | None = None, weekdays: collections.abc.Iterable[int] | None = None) list[tuple[datetime.datetime, datetime.datetime]][source]

Takes the given dates and generates the date tuples.

The except_for field will be considered if present, as will the on_holidays setting.

combine_datetime(field: str, time_field: str) datetime.datetime | None[source]

Takes the given date field and combines it with the given time field.

is_excluded(dt: datetime.datetime) bool[source]
class org.forms.allocation.AllocationRuleForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: onegov.form.Form

Base form form allocation rules.

property dates: collections.abc.Sequence[tuple[datetime.datetime, datetime.datetime]][source]
title[source]
extend[source]
property rule_id: str[source]
property iteration: int[source]
property last_run: datetime.datetime | None[source]
property rule: dict[str, Any][source]
property options: dict[str, Any][source]
apply(resource: onegov.reservation.Resource) int[source]
class org.forms.allocation.AllocationForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: onegov.form.Form, AllocationFormHelpers

Baseform for all allocation forms. Allocation forms are expected to implement the methods above (which contain a NotImplementedException).

Have a look at libres.db.scheduler.Scheduler.allocate() to find out more about those values.

request: onegov.org.request.OrgRequest[source]
start[source]
end[source]
except_for[source]
on_holidays[source]
during_school_holidays[source]
pricing_method[source]
price_per_item[source]
price_per_hour[source]
currency[source]
access[source]
on_request() None[source]
ensure_start_before_end() bool | None[source]
property weekdays: list[int][source]

The rrule weekdays derived from the except_for field.

property exceptions: DateContainer[source]
property ranged_exceptions: collections.abc.Sequence[tuple[datetime.date, datetime.date]][source]
is_excluded(dt: datetime.datetime) bool[source]
property dates: onegov.core.types.SequenceOrScalar[tuple[datetime.datetime, datetime.datetime]][source]
Abstractmethod:

Passed to libres.db.scheduler.Scheduler.allocate().

property whole_day: bool[source]
Abstractmethod:

Passed to libres.db.scheduler.Scheduler.allocate().

property partly_available: bool[source]
Abstractmethod:

Passed to libres.db.scheduler.Scheduler.allocate().

property quota: int[source]
Abstractmethod:

Passed to libres.db.scheduler.Scheduler.allocate().

property quota_limit: int[source]
Abstractmethod:

Passed to libres.db.scheduler.Scheduler.allocate().

property data: dict[str, Any][source]

Passed to libres.db.scheduler.Scheduler.allocate().

class org.forms.allocation.AllocationEditForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: onegov.form.Form, AllocationFormHelpers

Baseform for edit forms. Edit forms differ from the base allocation form somewhat, since they don’t offer a way to generate more than one allocation at a time.

The dates property is therefore expected to return a single start, end dates tuple.

date[source]
pricing_method[source]
price_per_item[source]
price_per_hour[source]
currency[source]
access[source]
property data: dict[str, Any][source]

Passed to libres.db.scheduler.Scheduler.allocate().

apply_data(data: dict[str, Any] | None) None[source]
class org.forms.allocation.Daypasses[source]
daypasses[source]
daypasses_limit[source]
class org.forms.allocation.DaypassAllocationForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationForm, Daypasses

Baseform for all allocation forms. Allocation forms are expected to implement the methods above (which contain a NotImplementedException).

Have a look at libres.db.scheduler.Scheduler.allocate() to find out more about those values.

whole_day = True[source]

Passed to libres.db.scheduler.Scheduler.allocate().

partly_available = False[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property quota: int[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property quota_limit: int[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property dates: collections.abc.Sequence[tuple[datetime.datetime, datetime.datetime]][source]

Passed to libres.db.scheduler.Scheduler.allocate().

class org.forms.allocation.DaypassAllocationEditForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationEditForm, Daypasses

Baseform for edit forms. Edit forms differ from the base allocation form somewhat, since they don’t offer a way to generate more than one allocation at a time.

The dates property is therefore expected to return a single start, end dates tuple.

whole_day = True[source]
partly_available = False[source]
property quota: int[source]
property quota_limit: int[source]
property dates: tuple[datetime.datetime, datetime.datetime][source]
apply_dates(start: datetime.datetime, end: datetime.datetime) None[source]
apply_model(model: onegov.reservation.Allocation) None[source]
class org.forms.allocation.RoomAllocationForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationForm

Baseform for all allocation forms. Allocation forms are expected to implement the methods above (which contain a NotImplementedException).

Have a look at libres.db.scheduler.Scheduler.allocate() to find out more about those values.

as_whole_day[source]
start_time[source]
end_time[source]
is_partly_available[source]
per_time_slot[source]
quota_limit = 1[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property quota: int[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property whole_day: bool[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property partly_available: bool[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property dates: collections.abc.Sequence[tuple[datetime.datetime, datetime.datetime]][source]

Passed to libres.db.scheduler.Scheduler.allocate().

class org.forms.allocation.DailyItemFields[source]
items[source]
item_limit[source]
class org.forms.allocation.DailyItemAllocationForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationForm, DailyItemFields

Baseform for all allocation forms. Allocation forms are expected to implement the methods above (which contain a NotImplementedException).

Have a look at libres.db.scheduler.Scheduler.allocate() to find out more about those values.

whole_day = True[source]

Passed to libres.db.scheduler.Scheduler.allocate().

partly_available = False[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property quota: int[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property quota_limit: int[source]

Passed to libres.db.scheduler.Scheduler.allocate().

property dates: collections.abc.Sequence[tuple[datetime.datetime, datetime.datetime]][source]

Passed to libres.db.scheduler.Scheduler.allocate().

class org.forms.allocation.DailyItemAllocationEditForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationEditForm, DailyItemFields

Baseform for edit forms. Edit forms differ from the base allocation form somewhat, since they don’t offer a way to generate more than one allocation at a time.

The dates property is therefore expected to return a single start, end dates tuple.

whole_day = True[source]
partly_available = False[source]
property quota: int[source]
property quota_limit: int[source]
property dates: tuple[datetime.datetime, datetime.datetime][source]
apply_dates(start: datetime.datetime, end: datetime.datetime) None[source]
apply_model(model: onegov.reservation.Allocation) None[source]
class org.forms.allocation.RoomAllocationEditForm(formdata: webob.multidict.MultiDict[str, Any] | None = None, obj: object | None = None, prefix: str = '', data: dict[str, Any] | None = None, meta: dict[str, Any] | None = None, *, extra_filters: collections.abc.Mapping[str, collections.abc.Sequence[Any]] | None = None, **kwargs: Any)[source]

Bases: AllocationEditForm

Baseform for edit forms. Edit forms differ from the base allocation form somewhat, since they don’t offer a way to generate more than one allocation at a time.

The dates property is therefore expected to return a single start, end dates tuple.

as_whole_day[source]
start_time[source]
end_time[source]
per_time_slot[source]
ensure_start_before_end() bool | None[source]
quota_limit = 1[source]
property quota: int[source]
property whole_day: bool[source]
property partly_available: bool[source]
property dates: tuple[datetime.datetime, datetime.datetime][source]
apply_dates(start: datetime.datetime, end: datetime.datetime) None[source]
apply_model(model: onegov.reservation.Allocation) None[source]
on_request() None[source]