def clone_occasion(self, request, form): if form.submitted(request): occasions = OccasionCollection(request.session) periods = PeriodCollection(request.session) form.populate_obj(occasions.add( activity=self.activity, start=form.parsed_dates[0].start, end=form.parsed_dates[0].end, timezone=form.timezone, period=periods.by_id(form.period_id.data) )) request.success(_("Your changes were saved")) return request.redirect(request.link(self.activity)) elif not request.POST: form.process(obj=self) return { 'layout': OccasionFormLayout( self.activity, request, _("Clone Occasion")), 'title': _("Clone Occasion"), 'form': form }
def recipients_which_are_active_organisers(self): occasions = OccasionCollection(self.request.session) q = occasions.query() q = q.join(Activity) q = q.join(Period) q = q.filter(Period.active == True) q = q.filter(Occasion.cancelled == False) q = q.with_entities(distinct(Activity.username).label('username')) return {o.username for o in q}
def recipients_by_occasion(self, occasions, include_organisers=True): q = self.recipients_by_occasion_query(occasions) q = q.with_entities(distinct(Booking.username).label('username')) attendees = {r.username for r in q} if not include_organisers: return attendees q = OccasionCollection(self.request.session).query() q = q.join(Activity) q = q.filter(Occasion.id.in_(occasions)) q = q.with_entities(distinct(Activity.username).label('username')) organisers = {r.username for r in q} return attendees | organisers
def occasions_by_period(session, activity, show_inactive, show_archived): query = OccasionCollection(session).query() query = query.filter(Occasion.activity_id == activity.id) query = query.join(Occasion.period) query = query.options(contains_eager(Occasion.period)) if not show_inactive: query = query.filter(Period.active == True) if not show_archived: query = query.filter(Period.archived == False) query = query.order_by( desc(Period.active), Period.execution_start, Occasion.order) return tuple( (title, tuple(occasions)) for title, occasions in groupby(query.all(), key=lambda o: o.period.title) )
def generate(request, app): owners = [ u.username for u in UserCollection(app.session()).by_roles('admin', 'editor') ] session = app.session() bound_generate_activity = partial( generate_activity, request=request, app=app, activities=VacationActivityCollection(session, identity=None), occasions=OccasionCollection(session), ) for n in range(0, count): bound_generate_activity(owner=random.choice(owners))
def populate_obj(self, model): super().populate_obj(model, exclude={ 'dates', 'max_spots', 'min_spots', 'min_age', 'max_age' }) assert self.parsed_dates, "should have been caught earlier" occasions = OccasionCollection(self.request.session) occasions.clear_dates(model) for date in sorted(self.parsed_dates): occasions.add_date(model, date.start, date.end, self.timezone) model.age = OccasionCollection.to_half_open_interval( self.min_age.data, self.max_age.data) model.spots = OccasionCollection.to_half_open_interval( self.min_spots.data, self.max_spots.data)
def get_occasion(request, app, id): return OccasionCollection(app.session()).by_id(id)
def test_notification_template_send_form(session): activities = ActivityCollection(session, type='vacation') attendees = AttendeeCollection(session) periods = PeriodCollection(session) occasions = OccasionCollection(session) bookings = BookingCollection(session) users = UserCollection(session) admin = users.add(username='******', realname='Robert Baratheon', password='******', role='admin') organiser = users.add(username='******', realname=None, password='******', role='editor') users.add(username='******', realname=None, password='******', role='member') prebooking = tuple(d.date() for d in (datetime.now() - timedelta(days=1), datetime.now() + timedelta(days=1))) execution = tuple(d.date() for d in (datetime.now() + timedelta(days=10), datetime.now() + timedelta(days=12))) period = periods.add(title="Ferienpass 2016", prebooking=prebooking, execution=execution, active=True) foo = activities.add("Foo", username='******') foo.propose().accept() bar = activities.add("Bar", username='******') bar.propose().accept() o1 = occasions.add( start=datetime(2016, 11, 25, 8), end=datetime(2016, 11, 25, 16), age=(0, 10), spots=(0, 2), timezone="Europe/Zurich", activity=foo, period=period, ) o1.username = admin.username o2 = occasions.add( start=datetime(2016, 11, 25, 17), end=datetime(2016, 11, 25, 20), age=(0, 10), spots=(0, 2), timezone="Europe/Zurich", activity=bar, period=period, ) o2.username = organiser.username a1 = attendees.add(admin, 'Dustin', date(2000, 1, 1), 'male') a2 = attendees.add(organiser, 'Mike', date(2000, 1, 1), 'female') b1 = bookings.add(admin, a1, o1) b1.state = 'accepted' b1.cost = 100 b2 = bookings.add(organiser, a2, o2) b2.state = 'accepted' b2.cost = 100 transaction.commit() # create a mock request def invoice_collection(user_id=None, period_id=None): return InvoiceCollection(session, user_id=user_id, period_id=period_id) def request(admin): return Bunch(app=Bunch( active_period=periods.active(), org=Bunch(geo_provider='geo-mapbox'), invoice_collection=invoice_collection, periods=periods.query().all(), ), session=session, include=lambda *args: None, model=None, is_admin=admin, is_organiser_only=not admin and True or False, is_manager=admin and True or False, translate=lambda text, *args, **kwargs: text, locale='de_CH', current_username=(admin and '*****@*****.**' or '*****@*****.**')) # in the beginning there are no recipients form = NotificationTemplateSendForm() form.model = None form.request = request(admin=True) assert form.has_choices # we still have choices (like send to users) assert not form.occasion.choices # once the request is processed, the occasions are added form.on_request() assert form.has_choices assert len(form.occasion.choices) == 2 assert len(form.send_to.choices) == 7 # if the period is inactive, there are no occasions periods.query().one().active = False transaction.commit() form = NotificationTemplateSendForm() form.model = None form.request = request(admin=True) form.on_request() assert len(form.occasion.choices) == 0 # if the period is active but not confirmed, there are no recipients period = periods.query().one() period.active = True period.confirmed = False transaction.commit() form = NotificationTemplateSendForm() form.model = None form.request = request(admin=True) form.on_request() occasions = [c[0] for c in form.occasion.choices] # with organisers assert len(form.recipients_by_occasion(occasions, True)) == 2 # without assert len(form.recipients_by_occasion(occasions, False)) == 0 # the number of users is indepenedent of the period assert len(form.recipients_by_role(('admin', 'editor', 'member'))) == 3 assert len(form.recipients_by_role(('admin', 'editor'))) == 2 assert len(form.recipients_by_role(('admin', ))) == 1 # if the period is confirmed, there are accepted recipients period = periods.query().one() period.active = True period.confirmed = True transaction.commit() assert len(form.recipients_by_occasion(occasions)) == 2 # only accepted bookings are counted parent = admin.username bookings.query().filter_by(username=parent).one().state = 'cancelled' transaction.commit() # without organisers assert len(form.recipients_by_occasion(occasions, False)) == 1 # with assert len(form.recipients_by_occasion(occasions, True)) == 2 # inactive users may be exluded form.state.data = ['active'] assert len(form.recipients_pool) == 3 form.state.data = ['active', 'inactive'] assert len(form.recipients_pool) == 3 form.state.data = ['inactive'] assert len(form.recipients_pool) == 0 # bookings count towards the wishlist if the period is active, period = periods.query().one() period.active = True period.confirmed = False transaction.commit() form.request = request(admin=True) # do not count cancelled bookings... assert len(form.recipients_with_wishes()) == 2 assert len(form.recipients_with_bookings()) == 0 # otherwise they count towards the bookings period = periods.query().one() period.confirmed = True transaction.commit() form.request = request(admin=True) assert len(form.recipients_with_wishes()) == 0 assert len(form.recipients_with_bookings()) == 2 # count the active organisers form.request = request(admin=True) assert len(form.recipients_which_are_active_organisers()) == 2 # count the users with unpaid bills form.request = request(admin=True) assert len(form.recipients_with_unpaid_bills()) == 0 period = periods.query().one() billing = BillingCollection(request=Bunch( session=session, app=Bunch(invoice_collection=invoice_collection)), period=period) billing.create_invoices() transaction.commit() form.request = request(admin=True) assert len(form.recipients_with_unpaid_bills()) == 1 # organisers are not counted as active if the occasion has been cancelled occasions = OccasionCollection(session) occasions.query().first().cancelled = True transaction.commit() form.request = request(admin=True) assert len(form.recipients_which_are_active_organisers()) == 1 for occasion in occasions.query(): occasion.cancelled = False transaction.commit() form.request = request(admin=True) assert len(form.recipients_which_are_active_organisers()) == 2
def delete_occasion(self, request): request.assert_valid_csrf_token() OccasionCollection(request.session).delete(self)