winterthur.daycare

Module Contents

Classes

Daycare

Service

Services

Result

Block

DirectoryDaycareAdapter

Settings

SubsidyResult

DaycareSubsidyCalculator

DaycareServicesWidget

DaycareServicesField

Field base class

DaycareSubsidyCalculatorForm

Extends wtforms.Form with useful methods and integrations needed in

Functions

round_to(→ decimal.Decimal)

format_precise(→ str)

format_1_cent(→ str)

format_5_cents(→ str)

Attributes

SERVICE_DAYS

SERVICE_DAYS_LABELS

FORMAT

winterthur.daycare.SERVICE_DAYS[source]
winterthur.daycare.SERVICE_DAYS_LABELS[source]
winterthur.daycare.FORMAT = '#,##0.00########'[source]
winterthur.daycare.round_to(n: decimal.Decimal, precision: str) decimal.Decimal[source]
winterthur.daycare.format_precise(amount: decimal.Decimal | None) str[source]
winterthur.daycare.format_1_cent(amount: decimal.Decimal) str[source]
winterthur.daycare.format_5_cents(amount: decimal.Decimal) str[source]
class winterthur.daycare.Daycare(id: uuid.UUID, title: str, rate: decimal.Decimal | float | str, weeks: int)[source]
property factor: decimal.Decimal[source]
class winterthur.daycare.Service[source]

Bases: NamedTuple

id: str[source]
title: str[source]
percentage: decimal.Decimal[source]
days: ordered_set.OrderedSet[int][source]
class winterthur.daycare.Services(definition: str | None)[source]
property total: decimal.Decimal | Literal[0][source]

Returns the total percentage of used services.

selected: dict[str, set[int]][source]
classmethod from_org(org: onegov.org.models.Organisation) typing_extensions.Self[source]
classmethod from_session(session: sqlalchemy.orm.Session) typing_extensions.Self[source]
static parse_definition(definition: str) Iterator[tuple[str, Service]][source]
select(service_id: str, day: int) None[source]
deselect(service_id: str, day: int) None[source]
is_selected(service_id: str, day: int) bool[source]
class winterthur.daycare.Result(title: str, amount: decimal.Decimal | None = None, note: str | None = None, operation: str | None = None, important: bool = False, currency: str | None = 'CHF', output_format: Callable[[Decimal], str] | None = None)[source]
property readable_amount: str[source]
__bool__() bool[source]
class winterthur.daycare.Block(id: str, title: str)[source]
results: list[Result][source]
op(title: str, amount: decimal.Decimal | None = None, note: str | None = None, operation: str | None = None, important: bool = False, currency: str | None = 'CHF', output_format: Callable[[Decimal], str] | None = None, total_places: int = 2, amount_places: int = 2) decimal.Decimal[source]
class winterthur.daycare.DirectoryDaycareAdapter(directory: onegov.org.models.ExtendedDirectory)[source]
fieldmap() dict[str, str | None][source]
as_daycare(entry: onegov.org.models.ExtendedDirectoryEntry) Daycare[source]
class winterthur.daycare.Settings(organisation: onegov.org.models.Organisation)[source]
directory: str[source]
max_income: decimal.Decimal[source]
max_rate: decimal.Decimal[source]
max_subsidy: decimal.Decimal[source]
max_wealth: decimal.Decimal[source]
min_income: decimal.Decimal[source]
min_rate: decimal.Decimal[source]
rebate: decimal.Decimal[source]
services: str[source]
wealth_premium: decimal.Decimal[source]
is_valid() bool[source]
factor(daycare: Daycare) decimal.Decimal[source]
class winterthur.daycare.SubsidyResult[source]

Bases: NamedTuple

blocks: tuple[Block, Ellipsis][source]
parent_share_per_month: str[source]
city_share_per_month: str[source]
total_per_month: str[source]
agenda: tuple[tuple[str, str | None, str], Ellipsis][source]
class winterthur.daycare.DaycareSubsidyCalculator(session: sqlalchemy.orm.Session)[source]
organisation() onegov.org.models.Organisation[source]
settings() Settings[source]
directory() onegov.org.models.ExtendedDirectory[source]
daycares() dict[str, Daycare][source]
daycare_by_title(title: str) Daycare[source]
calculate_precisely(daycare: Daycare, services: Services, income: decimal.Decimal, wealth: decimal.Decimal, rebate: bool) SubsidyResult[source]

Creates a detailed calculation of the subsidy paid by Winterthur.

The reslt is a list of tables with explanations.

Parameters:
  • daycare – The selected daycare (a Daycare instance).

  • services – Services used (a Services instance)

  • income – The income as a decimal.

  • wealth – The wealth as decimal.

  • rebate – True if a rebate is applied

Note, due to the specific nature of the content here, which is probably not going to be translated, we use German. For consistency we want to limit this, but with Winterthur these kinds of things crop up as the wording is quite specific and adding translations would just make this a lot harder.

class winterthur.daycare.DaycareServicesWidget[source]
property days: ordered_set.OrderedSet[int][source]
template[source]
__call__(field: DaycareServicesField, **kwargs: Any) markupsafe.Markup[source]
is_selected(service: Service, day: int) bool[source]
day_label(day: int) str[source]
class winterthur.daycare.DaycareServicesField(label=None, validators=None, filters=(), description='', id=None, default=None, widget=None, render_kw=None, name=None, _form=None, _prefix='', _translations=None, _meta=None)[source]

Bases: wtforms.fields.Field

Field base class

widget[source]
services() Services[source]
process_formdata(valuelist: list[Any]) None[source]

Process data received over the wire from a form.

This will be called during form construction with data supplied through the formdata argument.

Parameters:

valuelist – A list of strings to process.

pre_validate(form: wtforms.form.BaseForm) None[source]

Override if you need field-level validation. Runs before any other validators.

Parameters:

form – The form the field belongs to.

class winterthur.daycare.DaycareSubsidyCalculatorForm(formdata: 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: Mapping[str, 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): (0.85, '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.

property daycare_choices: Iterator[tuple[str, str]][source]
property selected_daycare: Daycare | None[source]
model: DaycareSubsidyCalculator[source]
daycare[source]
services[source]
income[source]
wealth[source]
rebate[source]
on_request() None[source]