class NewBookingConfirmForm(NewBookingPeriodForm): room_usage = RadioField( [DataRequired()], choices=[('current_user', _("I'll be using the room myself")), ('other_user', _("I'm booking the room for someone else"))]) booked_for_user = PrincipalField( _('User'), [HiddenUnless('room_usage', 'other_user'), DataRequired()], allow_external=True) booking_reason = TextAreaField(_('Reason'), [DataRequired()]) uses_vc = BooleanField(_('I will use videoconference equipment')) used_equipment = fossirQuerySelectMultipleCheckboxField( _('VC equipment'), get_label=lambda x: x.name) needs_vc_assistance = BooleanField( _('Request assistance for the startup of the videoconference session. ' 'This support is usually performed remotely.')) needs_assistance = BooleanField( _('Request personal assistance for meeting startup')) submit_book = SubmitField(_('Create booking')) submit_prebook = SubmitField(_('Create pre-booking')) def validate_used_equipment(self, field): if field.data and not self.uses_vc.data: raise ValidationError(_('Videoconference equipment is not used.')) elif not field.data and self.uses_vc.data: raise ValidationError( _('Please select the type of videoconference that you will use.' )) def validate_needs_vc_assistance(self, field): if field.data and not self.uses_vc.data: raise ValidationError(_('Videoconference equipment is not used.'))
class RoomForm(fossirForm): name = StringField(_(u'Name')) site = StringField(_(u'Site')) building = StringField(_(u'Building'), [DataRequired()]) floor = StringField(_(u'Floor'), [DataRequired()]) number = StringField(_(u'Number'), [DataRequired()]) longitude = FloatField(_(u'Longitude'), [Optional()]) latitude = FloatField(_(u'Latitude'), [Optional()]) is_active = BooleanField(_(u'Active'), default=True) is_reservable = BooleanField(_(u'Public'), default=True) reservations_need_confirmation = BooleanField(_(u'Confirmations')) notification_for_assistance = BooleanField(_(u'Assistance')) notification_before_days = IntegerField( _(u'Send booking reminders X days before (single/daily)'), [Optional(), NumberRange(min=1, max=30)]) notification_before_days_weekly = IntegerField( _(u'Send booking reminders X days before (weekly)'), [Optional(), NumberRange(min=1, max=30)]) notification_before_days_monthly = IntegerField( _(u'Send booking reminders X days before (monthly)'), [Optional(), NumberRange(min=1, max=30)]) notifications_enabled = BooleanField(_(u'Reminders enabled'), default=True) booking_limit_days = IntegerField( _(u'Maximum length of booking (days)'), [Optional(), NumberRange(min=1)]) owner = PrincipalField(_(u'Owner'), [DataRequired()], allow_external=True) key_location = StringField(_(u'Where is key?')) telephone = StringField(_(u'Telephone')) capacity = IntegerField(_(u'Capacity'), [Optional(), NumberRange(min=1)], default=20) division = StringField(_(u'Department')) surface_area = IntegerField(_(u'Surface area'), [Optional(), NumberRange(min=0)]) max_advance_days = IntegerField( _(u'Maximum advance time for bookings'), [Optional(), NumberRange(min=1)]) comments = TextAreaField(_(u'Comments')) delete_photos = BooleanField(_(u'Delete photos')) large_photo = FileField(_(u'Large photo')) small_photo = FileField(_(u'Small photo')) available_equipment = fossirQuerySelectMultipleCheckboxField( _(u'Equipment'), get_label=_get_equipment_label, modify_object_list=_group_equipment) # attribute_* - set at runtime bookable_hours = FieldList(FormField(_TimePair), min_entries=1) nonbookable_periods = FieldList(FormField(_DateTimePair), min_entries=1) def validate_large_photo(self, field): if not field.data and self.small_photo.data: raise ValidationError( _(u'When uploading a small photo you need to upload a large photo, too.' )) def validate_small_photo(self, field): if not field.data and self.large_photo.data: raise ValidationError( _(u'When uploading a large photo you need to upload a small photo, too.' ))
class AbstractReviewedForTracksForm(fossirForm): reviewed_for_tracks = fossirQuerySelectMultipleCheckboxField( _("Tracks"), get_label='title', collection_class=set) def __init__(self, *args, **kwargs): event = kwargs.pop('event') super(AbstractReviewedForTracksForm, self).__init__(*args, **kwargs) self.reviewed_for_tracks.query = Track.query.with_parent( event).order_by(Track.position)
class MultiTrackMixin(object): submitted_for_tracks = fossirQuerySelectMultipleCheckboxField( _("Tracks"), get_label='title', collection_class=set) def __init__(self, *args, **kwargs): event = kwargs['event'] self.track_field_disabled = ( kwargs.get('abstract') and kwargs['abstract'].edit_track_mode != EditTrackMode.both) if abstracts_settings.get( event, 'tracks_required') and not self.track_field_disabled: inject_validators(self, 'submitted_for_tracks', [DataRequired()]) super(MultiTrackMixin, self).__init__(*args, **kwargs) self.submitted_for_tracks.query = Track.query.with_parent( event).order_by(Track.position)
class SearchRoomsForm(fossirForm): location = QuerySelectField(_(u'Location'), get_label=lambda x: x.name, query_factory=Location.find, allow_blank=True) details = StringField() available = RadioField(_(u'Availability'), coerce=int, default=-1, widget=ConcatWidget(prefix_label=False), choices=[(1, _(u'Available')), (0, _(u'Booked')), (-1, _(u"Don't care"))]) capacity = IntegerField(_(u'Capacity'), validators=[Optional(), NumberRange(min=0)]) available_equipment = fossirQuerySelectMultipleCheckboxField( _(u'Equipment'), get_label=_get_equipment_label, modify_object_list=_group_equipment, query_factory=lambda: EquipmentType.find().order_by(EquipmentType.name )) is_only_public = BooleanField(_(u'Only public rooms'), default=True) is_auto_confirm = BooleanField(_(u'Only rooms not requiring confirmation'), default=True) is_only_active = BooleanField(_(u'Only active rooms'), default=True) is_only_my_rooms = BooleanField(_(u'Only my rooms')) # Period details when searching for (un-)availability start_dt = DateTimeField(_(u'Start date'), validators=[Optional()], parse_kwargs={'dayfirst': True}, display_format='%d/%m/%Y %H:%M', widget=HiddenInput()) end_dt = DateTimeField(_(u'End date'), validators=[Optional()], parse_kwargs={'dayfirst': True}, display_format='%d/%m/%Y %H:%M', widget=HiddenInput()) repeatability = StringField( ) # TODO: use repeat_frequency/interval with new UI include_pending_blockings = BooleanField( _(u'Check conflicts against pending blockings'), default=True) include_pre_bookings = BooleanField( _(u'Check conflicts against pre-bookings'), default=True)
class AbstractReviewForm(fossirForm): """Form for reviewing an abstract""" _order = ('proposed_action', 'proposed_contribution_type', 'proposed_related_abstract', 'proposed_tracks', 'comment') comment = TextAreaField(_("Comment"), render_kw={ 'placeholder': _("You may leave a comment (only visible to " "conveners and judges)...") }) proposed_action = fossirEnumSelectField(_("Proposed Action"), [DataRequired()], enum=AbstractAction) proposed_related_abstract = AbstractField( _("Target Abstract"), [ HiddenUnless( 'proposed_action', {AbstractAction.mark_as_duplicate, AbstractAction.merge}), DataRequired() ], description= _("The current abstract should be marked as duplicate of the selected one" ), ajax_endpoint='abstracts.other_abstracts') proposed_contribution_type = QuerySelectField( _("Contribution type"), [HiddenUnless('proposed_action', AbstractAction.accept)], get_label=lambda x: x.name.title(), allow_blank=True, blank_text=_("You may propose a contribution type...")) proposed_tracks = fossirQuerySelectMultipleCheckboxField( _("Propose for tracks"), [ HiddenUnless('proposed_action', AbstractAction.change_tracks), DataRequired() ], collection_class=set, get_label='title') def __init__(self, edit=False, *args, **kwargs): abstract = kwargs.pop('abstract') super(AbstractReviewForm, self).__init__(*args, **kwargs) self.event = abstract.event if not edit: self.proposed_action.none = _("Propose an action...") self.proposed_related_abstract.excluded_abstract_ids = {abstract.id} self.proposed_contribution_type.query = ( ContributionType.query.with_parent(self.event).order_by( ContributionType.name)) if not self.proposed_contribution_type.query.count(): del self.proposed_contribution_type reviewed_for_track_ids = {t.id for t in abstract.reviewed_for_tracks} existing_prop_track_cond = (Track.id.in_( t.id for t in self.proposed_tracks.object_data) if self.proposed_tracks.object_data else False) self.proposed_tracks.query = (Track.query.with_parent( self.event).filter( db.or_(Track.id.notin_(reviewed_for_track_ids), existing_prop_track_cond)).order_by(Track.position)) if not self.proposed_tracks.query.count(): del self.proposed_tracks self.proposed_action.skip.add(AbstractAction.change_tracks) @property def split_data(self): data = self.data return { 'questions_data': {k: v for k, v in data.iteritems() if k.startswith('question_')}, 'review_data': { k: v for k, v in data.iteritems() if not k.startswith('question_') } }