Source code for org.pricing_schemes.horw

from datetime import timedelta
from onegov.form import move_fields
from onegov.form.fields import FieldTable
from onegov.org import _, log
from onegov.reservation import Resource, ResourcePricingScheme
from wtforms.fields import DecimalField
from wtforms.validators import InputRequired, NumberRange


from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
    from collections.abc import Collection
    from decimal import Decimal
    from onegov.form import Form
    from onegov.form.parser.core import RadioField
    from onegov.org.request import OrgRequest
    from onegov.reservation import Reservation


[docs] class HorwHorwerhalle( ResourcePricingScheme, name='horw_horwerhalle', label='Horwerhalle (exkl. Küche/Bühne)', content_names=( 'horw_horwerhalle_price_table', 'horw_horwerhaller_non_profit_field', 'horw_horwerhaller_wirtschaft_field', ) ): @classmethod
[docs] def reservation_unit_price( cls, reservation: Reservation, resource: Resource, submission_data: dict[str, Any] | None ) -> Decimal | None: if submission_data is None: return None data = (reservation.data or {}) non_profit = submission_data.get(data.get( 'horw_horwerhaller_non_profit_field', 'horwer_non_profit_organisation' )) == 'Ja' wirtschaft = submission_data.get(data.get( 'horw_horwerhaller_wirtschaft_field', 'mit_wirtschaft' )) == 'Ja' table = data.get('horw_horwerhalle_price_table') if table is None: table = resource.content.get('horw_horwerhalle_price_table') if table is None: log.error( f'Pricing table missing for pricing scheme horw_horwerhalle ' f'on reservation {reservation.id}' ) return None start, end = reservation.start, reservation.end assert start is not None and end is not None # special-case where it is always free if non_profit and not wirtschaft and start.weekday() < 5: return None two_hours, half_day, full_day = table[ (0 if non_profit else 2) + (1 if wirtschaft else 0) ] duration = end + timedelta(microseconds=1) - start if duration < timedelta(hours=2): return two_hours elif duration < timedelta(hours=5): return half_day else: return full_day
@classmethod
[docs] def extend_form[T: Form]( cls, form_class: type[T], request: OrgRequest ) -> type[T]: class HorwerhalleForm(form_class): # type:ignore horw_horwerhalle_price_table = FieldTable( DecimalField(validators=[InputRequired(), NumberRange(min=0)]), ['2 h', '½ Tag', '1 Tag'], [ 'Horwer Non-Profit ohne Wirtschaft', 'Horwer Non-Profit mit Wirtschaft', 'Übrige ohne Wirtschaft', 'Übrige mit Wirtschaft' ], label='Preistabelle', fieldset=_('Payments'), depends_on=( 'pricing_method', 'pricing_scheme', 'pricing_scheme', cls.name ) ) def process_obj(self, obj: object) -> None: super().process_obj(obj) if not request.POST and isinstance(obj, Resource): self.horw_horwerhalle_price_table.data = obj.content.get( 'horw_horwerhalle_price_table') def populate_obj( self, obj: Resource, exclude: Collection[str] | None = None, include: Collection[str] | None = None ) -> None: exclude = {'horw_horwerhalle_price_table', *(exclude or ())} super().populate_obj(obj, exclude, include) obj.content['horw_horwerhalle_price_table'] = ( self.horw_horwerhalle_price_table.data) if field := self.get_non_profit_field(): obj.content[ 'horw_horwerhaller_non_profit_field' ] = field.id elif 'horw_horwerhaller_non_profit_field' in obj.content: del obj.content['horw_horwerhaller_non_profit_field'] if field := self.get_wirtschaft_field(): obj.content[ 'horw_horwerhaller_wirtschaft_field' ] = field.id elif 'horw_horwerhaller_wirtschaft_field' in obj.content: del obj.content['horw_horwerhaller_wirtschaft_field'] def get_non_profit_field(self) -> RadioField | None: parsed = self['parsed'].data if parsed is None: return None for field in parsed.fields: if field.type != 'radio': continue if 'Non-Profit' in field.label: return field return None def get_wirtschaft_field(self) -> RadioField | None: parsed = self['parsed'].data if parsed is None: return None for field in parsed.fields: if field.type != 'radio': continue if 'Wirtschaft' in field.label: return field return None def ensure_valid_form_definition(self) -> bool | None: if 'pricing_scheme' not in self: return None if self['pricing_method'].data != 'pricing_scheme': return None if self['pricing_scheme'].data != 'horw_horwerhalle': return None if self['parsed'].errors: # if we failed to parse, don't pile on more errors return None non_profit_field = self.get_non_profit_field() if ( non_profit_field is None or not any( choice.label == 'Ja' for choice in non_profit_field.choices ) ): self['parsed'].errors.append( 'Mit Preisschema "Horwerhalle" braucht es ein Feld ' 'mit "Non-Profit" im Namen, mit einer "Ja" Antwort, ' 'welche bedeutet, dass es sich um eine Horwer ' 'Non-Profit Organisation handelt.' ) return False elif not non_profit_field.required: self['parsed'].errors.append( f'Mit Preisschema "Horwerhalle" darf das Feld ' f'"{non_profit_field.label}" nicht optional sein.' ) return False wirtschaft_field = self.get_wirtschaft_field() if ( wirtschaft_field is not None and not any( choice.label == 'Ja' for choice in wirtschaft_field.choices ) ): self['parsed'].errors.append( 'Mit Preisschema "Horwerhalle" braucht ein Feld ' 'mit "Wirtschaft" im Namen, eine "Ja" Antwort, ' 'welche bedeutet, dass die Halle mit Wirtschaft ' 'reserviert wird.' ) return False return None return move_fields( HorwerhalleForm, ('horw_horwerhalle_price_table',), after='pricing_scheme' )